C++二叉树二(练习题)

【创建二叉树求深度】

给出一棵二叉树的先序与中序排列。求出它的深度。(约定树结点用不同的大写字母表示,长度<=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
*/
相关推荐
晚风醉蝶2 小时前
1-6-插入排序-InsertionSort
java·数据结构·排序算法
Tyler_TXZ2 小时前
C++C语言之——二叉树
c语言·开发语言·数据结构·c++·二叉树
Tisfy2 小时前
LeetCode 3090.每个字符最多出现两次的最长子字符串:二重循环 / 滑动窗口
算法·leetcode·字符串·题解·模拟·双指针·滑动窗口
-dzk-2 小时前
【技巧】LC 136.只出现一次的数字
算法·异或
不会代码的小猴2 小时前
C++新增关键字
开发语言·c++·笔记
专注仿真3 小时前
问答大模型技术方案算法实现-RAPTOR树构建算法与BEG集成使用
python·算法
liulilittle3 小时前
并发与内存安全术语:定义、分类与关联
c++·安全·并发·术语
_wyt0013 小时前
从图到树:9道洛谷基础题带你入门树形结构
c++·
zlinear数据采集卡3 小时前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源