C++03阶段练习(练习题)

二叉树的最小深度

【描述】给定一棵二叉树, 求该二叉树的最小深度。二叉树的最小深度就是从根结点到最近的叶结点的路径上的结点数量。

【输入描述】第一行是一个正整数 n, 表示二叉树的结点个数。 二叉树结点编号从 1到 n, 根结点为 1, n <= 10 。接下来有 n 行, 依次对应二叉树的结点1~n。

每行有两个整数, 分别表示该结点的左儿子和右儿子的结点编号。 如果第一个(第二个) 数为-1 则表示没有左(右)儿子。

【输出描述】输出一个整型数, 表示树的最小深度。

【输入样例】

7

2 7

3 6

4 5

-1 -1

-1 -1

-1 -1

-1 -1

【输出样例】

2

cpp 复制代码
#include<iostream>
#include<queue> 
using namespace std;

struct tree_node{
	int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号 
};
tree_node tree[11];
int n;
queue<int> q;


int getMinDepth(){
	int depth=0;
	// 根结点编号1,入队
	q.push(1);
	while(!q.empty()){
		depth++;
		int levelCount = q.size();// 每层的节点数 
		
		while(levelCount>0){// 逐个处理这一层的结点 
			levelCount--;
			
			int id = q.front();
			q.pop();
			if(tree[id].ls==-1 && tree[id].rs==-1)//第一个叶子结点 
				return depth; 
			// 先左后右,子结点(编号)入队 
			if(tree[id].ls != -1)
				q.push(tree[id].ls); 
			if(tree[id].rs != -1)
				q.push(tree[id].rs);	
		} 
	} 
} 

int main(){
	// 读入和保存树 
	cin >> n;
	for(int i=1;i<=n;i++){
	 	cin >> tree[i].ls >> tree[i].rs; 
	}
	// 以层序遍历方式获得最小深度 
	cout << getMinDepth(); 
	return 0; 
}
/*
本题测试点
【样例输入1】
1
-1 -1
【样例输出1】
1
【样例输入2】
7
2 3
4 5
6 7
-1 -1
-1 -1
-1 -1
-1 -1
【样例输出2】
3
【样例输入3】
4
2  -1
3  -1
4  -1
-1 -1
【样例输出3】
4
【样例输入4】
3
2 -1
-1 -1
-1 -1
【样例输出4】
2
【样例输入5】
2 3
-1 4
-1 -1
-1 -1
-1 -1
【样例输出5】
2
*/

二叉树的角结点

【描述】给定一棵二叉树, 输出该二叉树的所有角结点。二叉树的角结点指每层的最左边的结点和最右边的结点。例如右图的二叉树,按层次从左到右输出所有角结点: 1 2 6 3 7 5。

【输入描述】第一行是一个正整数 n, 表示二叉树的结点个数。 二叉树结点编号从 1到 n, 根结点为 1, n <= 10 。接下来有 n 行, 依次对应二叉树的结点1~n。

每行有两个整数, 分别表示该结点的左儿子和右儿子的结点编号。 如果第一个(第二个) 数为-1 则表示没有左(右)儿子。

【输出描述】按从上到下、从左到右输出所有角结点。

【输入样例】

7

2 6

3 4

-1 -1

5 -1

-1 -1

-1 7

-1 -1

【输出样例】

1 2 6 3 7 5

cpp 复制代码
#include<iostream>
#include<queue> 
using namespace std;

struct tree_node{
	int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号 
};
tree_node tree[11];
int n;
queue<int> q;

void printCornerNodes(){
	// 根结点编号1,入队
	q.push(1);
	while(!q.empty()){
		int levelCount = q.size();// 当前层的节点数 
		for(int i=levelCount;i>0;i--){// 处理这一层的结点 
			int id = q.front();
			q.pop();
			//每层第一个元素即最左结点
			//每层最后一个元素即最右结点 
			if(i==levelCount || i==1)
				cout << id << " "; 
			// 先左后右,子结点(编号)入队 
			if(tree[id].ls != -1)
				q.push(tree[id].ls); 
			if(tree[id].rs != -1)
				q.push(tree[id].rs);	
		} 
	} 
} 

int main(){
	// 读入和保存树 
	cin >> n;
	for(int i=1;i<=n;i++){
	 	cin >> tree[i].ls >> tree[i].rs; 
	}
	// 以层序遍历方式打印角结点 
	printCornerNodes(); 
	return 0; 
}
/*
本题测试点
【样例输入1】
3
3 -1
-1 -1
2 -1
【样例输出1】
1 3 2
【样例输入2】
7
2 7
3 6
4 5
-1 -1
-1 -1
-1 -1
-1 -1
【样例输出2】
1 2 7 3 6 4 5
【样例输入3】
7
2 3
4 5
6 7
-1 -1
-1 -1
-1 -1
-1 -1
【样例输出3】
1 2 3 4 7
【样例输入4】
10
2 10
3 -1
4 9
5 8
6 7
-1 -1
-1 -1
-1 -1
-1 -1
-1 -1
【样例输出4】
1 2 10 3 4 9 5 8 6 7
【样例输入5】
10
2 3
4 5
6 7
8 -1
-1 9
-1 -1
-1 10
-1 -1
-1 -1
-1 -1
【样例输出5】
1 2 3 4 7 8 10
*/

判断平衡二叉树

【描述】给定一棵二叉树, 判断该二叉树的是否平衡二叉树。

平衡二叉树指树的每个结点的两个子树的高度差都不能超过1。 反之任意一个结点的左右子树的高度差>1,则这个树不是平衡二叉树。 只有一个结点的树也是平衡二叉树。

【输入描述】第一行是一个正整数 n, 表示二叉树的结点个数。 二叉树结点编号从 1到 n, 根结点为 1, n <= 10 。接下来有 n 行, 依次对应二叉树的结点1~n。

每行有两个整数, 分别表示该结点的左儿子和右儿子的结点编号。 如果第一个(第二个) 数为-1 则表示没有左(右)儿子。

【输出描述】这个树是平衡二叉树,输出"yes",否则输出"no"。

【输入样例】

7

2 6

3 4

-1 -1

5 -1

-1 -1

-1 7

-1 -1

【输出样例】

yes

cpp 复制代码
#include<iostream>
using namespace std;

struct tree_node{
	int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号 
};
tree_node tree[11];
int n;

int depth(int root){
	if(root == -1 ) return 0;
	// 树的深度=左右子树深度较大者+1 
	return max(depth(tree[root].ls),depth(tree[root].rs))+1;
}

bool isBalanced(int root){
	if(root == -1 ) return true;
	// 树平衡:左右子树必须平衡,且左右子树深度差<=1 
	if(!isBalanced(tree[root].ls) || !isBalanced(tree[root].rs))
		return false;
	int lDepth = depth(tree[root].ls); 
	int rDepth = depth(tree[root].rs); 
	if(abs(lDepth-rDepth)>1) return false;
	return true;
} 

int main(){
	// 读入和保存树 
	cin >> n;
	for(int i=1;i<=n;i++){
	 	cin >> tree[i].ls >> tree[i].rs; 
	}
	// 是否平衡二叉树 
	if(isBalanced(1))
		cout << "yes";
	else 
		cout << "no";
	return 0; 
}
/*
本题测试点
【样例输入1】
1
-1 -1 
【样例输出1】
yes
【样例输入2】
3
3 -1
-1 -1
2 -1
【样例输出2】
no
【样例输入3】
3
2 3
-1 -1
-1 -1
【样例输出3】
yes
【样例输入4】
7
2 6
3 4
-1 -1
5 -1
-1 -1
-1 7
-1 -1
【样例输出4】
yes
【样例输入5】
7
2 7
3 6
4 5
-1 -1
-1 -1
-1 -1
-1 -1
【样例输出5】
no
*/

右叶结点的和

【描述】给定一棵二叉树, 求所有右叶结点值的和。

【输入描述】

第一行是一个正整数 n, 表示二叉树的结点个数。 二叉树结点编号从 1到 n, 根结点为 1, n <= 10 。接下来有 n 行, 依次对应二叉树的结点1~n。

每行有3个整数, 分别表示该结点的值、左儿子和右儿子的结点编号。 如果第2个(第3个) 数为-1 则表示没有左(右)儿子。

【输出描述】

输出一个整型数, 表示所有右叶结点值的和。

【输入样例】

7

12 2 6

3 3 4

5 -1 -1

0 5 -1

0 -1 -1

6 -1 7

7 -1 -1

【输出样例】

7

【提示】

方法1:层序遍历时保持两个队列,一个层序过程中的结点(编号)队列,一个结点是否右子结点的标记队列。

保持两个队列同步(一一对应)

方法2:在结点结构体中增加一个标记,标记当前结点是否是某个父结点的右子结点。

cpp 复制代码
#include<iostream>
#include<queue> 
using namespace std;

struct tree_node{
	int value;
	int ls,rs; //ls:左孩子结点编号,rs:右孩子结点编号 
};
tree_node tree[11];
int n;
queue<int> q; // 层序遍历:结点编号队列
queue<bool> qFlag; // 层序遍历:结点是否右结点的标记队列 

int rightLeavesSum(){
	int sum = 0;
	// 根结点编号1,入队
	q.push(1);
	qFlag.push(false); 
	while(!q.empty()){
		int levelCount = q.size();// 当前层的节点数 
		for(int i=levelCount;i>0;i--){// 处理这一层的结点 
			int id = q.front();
			int isRightSon =  qFlag.front(); 
			q.pop();
			qFlag.pop(); 
			//是右结点且是叶结点,计算和 
			if(isRightSon && tree[id].ls == -1 &&  tree[id].rs == -1)
				sum += tree[id].value; 
			// 先左后右,子结点(编号)入队 
			if(tree[id].ls != -1){
				q.push(tree[id].ls); 
				qFlag.push(false);
			}
				
			if(tree[id].rs != -1){
				q.push(tree[id].rs);
				qFlag.push(true); 	
			}
				
		} 
	} 
	return sum; 
} 

int main(){
	// 读入和保存树 
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> tree[i].value ;
	 	cin >> tree[i].ls >> tree[i].rs; 
	}
	// 计算所有右叶结点之和 
	cout << rightLeavesSum(); 
	return 0; 
}
/*
本题测试点
【样例输入1】
3
1 3 -1
3 -1 -1
7 2 -1
【样例输出1】
0
【样例输入2】
3
1 2 3
3 -1 -1
7 -1 -1
【样例输出2】
7
【样例输入3】
7
12 2 6
3 3 4
5 -1 -1
0 5 -1
0 -1 -1
6 -1 7
7 -1 -1
【样例输出3】
7
【样例输入4】
7
12 2 7
0 3 6
5 4 5
0 -1 -1
7 -1 -1
4 -1 -1
8 -1 -1
【样例输出4】
19
【样例输入5】
7
12 2 6
3 3 4
5 -1 -1
4 5 -1
0 -1 -1
6 -1 7
0 -1 -1
【样例输出5】
0
*/
相关推荐
灯澜忆梦8 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
禾小西8 小时前
Redis 数据结构:快速的 Redis 有哪些慢操作?
数据结构·数据库·redis
小蒋观天下8 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J8 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有9 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu1111119 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS9 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b10 小时前
算法日常・每日刷题--<动态规划>14
算法
赛博守夜人10 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全