【创建二叉树求深度】
给出一棵二叉树的先序与中序排列。求出它的深度。(约定树结点用不同的大写字母表示,长度<=8)。
二叉树深度的定义: 从根结点到最远叶结点依次经过的结点个数(含根、叶结点)。
【输入描述】 两行,每行一个字符串,分别表示先序和中序排列。
【输出描述】 一个整数表示二叉树的深度。
【输入样例1】
ABDCEGF
DBAEGCF
【输出样例1】
4
【输入样例2】
ABEFDC
EBFADC
【输出样例2】
3
cpp
#include<iostream>
#include<cstring>
using namespace std;
#define LEN 9
struct tree_node{
int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号
char value;
};
tree_node tree[LEN]; //保存构建的二叉树, 下标1开始放
char preorder[LEN]; //先序序列
char inorder[LEN]; //中序序列
int p = 1; //在tree[]中放入结点的位置下标
//
// 返回二叉树的根结点的编号(下标)
// 先序序列和中序序列分别保存在全局变量preorder[]、inorder[]中
// preStart、preEnd:先序序列的下标范围
// inStart、inEnd:中序序列的下标范围
int buildTree(int preStart, int preEnd, int inStart, int inEnd){
//递归出口,序列长度不足1,返回空节点编号
if(preStart > preEnd || inStart > inEnd) return 0;
// 根结点的值先放入tree[]中p指向的位置
tree[p].value = preorder[preStart];
// 保存根结点的下标
int rootId = p++;
// 找到根结点在中序序列中的下标
int i=inStart;
while(i <= inEnd && preorder[preStart] != inorder[i])
i++;
// 算出左子树的长度
int len = i-inStart;
// 递归构建左右子树,并把返回的子树跟结点编号存入根结点的 ls,rs
tree[rootId].ls = buildTree(preStart+1, preStart+len, inStart, i-1);
tree[rootId].rs = buildTree(preStart+len+1,preEnd,i+1,inEnd);
return rootId; //根在tree数组中的下标
}
// 递归地求以root结点为根的树的深度(最远叶结点到根的结点个数)
// 树的深度 = 左右子树深度较大的那个值 + 1
int depth(int root){
if(root == 0) // 空节点深度0
return 0;
return max(depth(tree[root].ls),depth(tree[root].rs)) + 1;
}
int main(){
// 读入
cin >> preorder >> inorder;
int len = strlen(preorder); //输入的序列长度
int rootid = buildTree(0,len-1,0,len-1);
cout << depth(rootid);
return 0;
}
/*
本题测试点
【样例输入1】
A
A
【样例输出1】
1
【样例输入2】
ABD
DBA
【样例输出2】
3
【样例输入3】
ABDECFG
DBEAFCG
【样例输出3】
3
【样例输入4】
12345
43251
【样例输出4】
4
【样例输入5】
ABCDEFGHI
EDCBAGFHI
【样例输出5】
5
*/
新二叉树
【题目描述】
输入一串二叉树,输出其前序遍历。
【输入描述】二叉树的前序遍历。
一行是二叉树的结点数n(1≤n≤26)。
接下来n行,每行3个小写字符。第一个字母表示为结点,后两个字母分别是其左右儿子。若
孩子结点是空结点,用代替。注意:数据第一行结点是根结点。
【输出描述】
二叉树的前序遍历。
【输入样例】
6
bfc
fdi
c**
dj
i**
j**
【输出样例】
bfdjic
cpp
#include<iostream>
using namespace std;
struct Node {
char data; // 结点的值
int left,right; //左右子结点编号
}BTree[30];//n的范围1≤n≤26
int n;
int root; //根结点下标
void preOrder(int root) {
if (root != 0) {
cout << BTree[root].data;
preOrder(BTree[root].left);
preOrder(BTree[root].right);
}
}
int main(){
// 读入和保存树
cin >> n;
for (int i = 1; i <= n; i++) {
char a, b,c;//父、左右孩子
cin >> a >> b >> c;
int id = a - 'a' + 1;
if(i==1) root = id; //保存根结点下标 (编号)
//1.存储结点值
BTree[id].data = a;
//2.存储左孩子编号
if (b != '*') BTree[id].left = b - 'a' + 1;
else BTree[id].left = 0;
//3.存储右孩子编号
if (c != '*') BTree[id].right = c - 'a' + 1;
else BTree[id].right = 0;
}
// 先序遍历
preOrder(root);
return 0;
}
/*
本题测试点
【样例输入1】
1
a**
【样例输出1】
a
【样例输入2】
8
abc
bef
cd*
d*h
e**
fg*
g**
h**
【样例输出2】
abefgcdh
【样例输入3】
4
bc*
cd*
de*
e**
【样例输出3】
bcde
【样例输入4】
4
cb*
ba*
ad*
d**
【样例输出4】
cbad
【样例输入5】
4
c*b
b*a
a*d
d**
【样例输出5】
cbad
*/
对称二叉树
【题目描述】给定一棵二叉树,请编程判断是否是对称二叉树。对称二叉树的定义:将这棵二叉树所有节点的左右子树交换,新树和原树对应位置的结构相同且结点值相等,这样的二叉树称为对称二叉树。只有给定的树是对称二叉树时,才返回true;否则返回false。
【输入描述】
第一行一个正整数 ,表示给定的树的节点的数目,规定节点编号1~n ,其中节点 1 是树根。
第二行 n个正整数,用一个空格分隔,第 i 个正整数代表节点i的值。
接下来 n 行,每行两个正整数li、ri,分别表示节点 i 的左右孩子的编号。如果不存在左 / 右孩子,则以 -1 表示。两个数之间用一个空格隔开。
【输出描述】
是对称二叉树输出"true",否则输出"false"。
【输入样例】
7
1 2 2 3 4 4 3
2 3
4 5
6 7
-1 -1
-1 -1
-1 -1
-1 -1
【输出样例】
true
cpp
#include<iostream>
using namespace std;
struct tree_node{
int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号
int value;
};
tree_node tree[11];
int n;
int list[11];//放置中序序列
int p = 1; //list[]当前位置
//中序遍历递归函数
void inOrder(int root){
if(root!=-1){
inOrder(tree[root].ls);//1、递归遍历左子树
list[p] = tree[root].value; //2、根结点值放入中序序列list
p++;
inOrder(tree[root].rs);//3、递归遍历右子树
}
}
int main()
{
// 读入和保存树
cin >> n;
if(n%2 == 0) { //偶数个结点不可能是对称二叉树
cout << "false";
return 0;
}
for(int i=1;i<=n;i++){
cin >> tree[i].value;
}
for(int i=1;i<=n;i++){
cin >> tree[i].ls >> tree[i].rs;
}
// 生成中序序列
inOrder(1);
// 判断中序序列是否回文(对称)
bool flag = true;//默认是对称
for(int i=1,j=n; i<=j;i++,j--){
if(list[i]!=list[j]){
flag = false;
break;
}
}
if(flag)
cout << "true";
else
cout << "false";
return 0;
}
/*
本题测试点
【样例输入1】
7
1 2 3 2 4 4 3
2 4
3 5
-1 -1
6 7
-1 -1
-1 -1
-1 -1
【样例输出1】
true
【样例输入2】
1
3
-1 -1
【样例输出2】
true
【样例输入3】
3
3 1 2
3 2
-1 -1
-1 -1
【样例输出3】
false
【样例输入4】
3
3 2 2
2 -1
3 -1
-1 -1
【样例输出4】
false
【样例输入5】
4
3 2 2 3
2 4
3 -1
-1 -1
-1 -1
【样例输出5】
false
*/
二叉树的路径
【题目描述】
给定一棵二叉树,找出所有从根节点到叶子节点的路径。
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。叶子节点是指没有子节点的节点。
【输入描述】第一行是一个整数 n, 表示二叉树的结点个数。 二叉树结点编号从 1到 n(1<= n <= 10) , 根结点为 1。接下来有 n 行, 依次对应二叉树的 n 个结点。
【输出描述】多行,一行一个路径。路径由从根到叶的结点编号组成。多个路径按先左后右顺序输出。
【输入样例】
7
2 6
3 4
-1 -1
5 -1
-1 -1
-1 7
-1 -1
【输出样例】
1 2 3
1 2 4 5
1 6 7
cpp
#include<iostream>
using namespace std;
struct tree_node{
int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号
};
tree_node tree[11];
int n;
int path[11];
int p = 0;
//先序遍历递归函数
void preOrder(int root){
if(root != -1){//非空树才能遍历
path[p] = root; //1、访问根(根结点编号加入路径)
p++;
preOrder(tree[root].ls); //2、递归遍历左子树
preOrder(tree[root].rs); //3、递归遍历右子树
if(tree[root].ls == -1 && tree[root].rs== -1 ) {// 到叶节点说明一条路径结束
// 输出路径
for(int i=0;i<p;i++)
cout<<path[i]<<" ";
cout<<endl;
}
// 回溯,这个结点信息从路径移走
p--;
}
}
int main()
{
// 读入和保存树
cin >> n;
for(int i=1;i<=n;i++){
cin >> tree[i].ls >> tree[i].rs;
}
//用先序遍历方式找所有路径
preOrder(1);
return 0;
}
/*
本题测试点
【样例输入1】
7
2 6
3 4
-1 -1
5 -1
-1 -1
-1 7
-1 -1
【样例输出1】
1 2 3
1 2 4 5
1 6 7
【样例输入2】
10
2 10
3 -1
4 9
5 8
6 7
-1 -1
-1 -1
-1 -1
-1 -1
-1 -1
【样例输出2】
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 8
1 2 3 9
1 10
【样例输入3】
1
-1 -1
【样例输出3】
1
【样例输入4】
3
2 3
-1 -1
-1 -1
【样例输出4】
1 2
1 3
【样例输入5】
3
3 -1
-1 -1
2 -1
【样例输出5】
1 3 2
*/