[C++日常小题] 计算二叉查找树的高度
来源:互联网 发布:js api demo 编辑:程序博客网 时间:2024/06/13 00:23
Description
给定一个二叉查找树,要求计算其高度,每个二叉查找树将给出先序与中序的遍历。
例如:一个二叉查找树其先序遍历为:16, 10, 4, 15, 23 ; 中序遍历为 4, 10, 15, 16, 23,则其高度为2(假定空树高度为-1,只有根节点的数高度为0)
Input
第一行输入测试用例个数。
对于每个测试用例,
第一行是节点个数n,第二行是key值的先序遍历,第三行是key值的中序遍历
Output
对于每个测试用例,用一行输出树的高度
Sample Input
2
3
4 5 6
4 5 6
5
6 4 8 9 10
4 6 8 9 10
Sample Output
2
3
解题思路
首先,根据二叉树的遍历特性
- 先序遍历: 首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
- 中序遍历: 首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。
可以推出,先序遍历的第一个元素就为二叉树的根结点。
又在中序遍历中,若找到根节点,则根节点左侧的为其左子树结点,右侧的为其右子树结点。
为了更方便阐述,设几个变量
- root: 当前根结点在先序遍历中的下标
- pos: 当前根结点在中序遍历中的下标
- left: 根树或子树的所有结点在中序遍历中的下标范围的左边界
- right: 根树或子树的所有结点在中序遍历中的下标范围的右边界(结点不包括右边界)
若根结点有左子树,则先序遍历中下标为 root + 1
的结点为其左子树的根结点,[left, pos)
为其左子树的所有结点。
当前根结点在先序遍历中下标为 root + pos - left + 1
的结点为右子树的根结点,[pos + 1, right)
为其右子树的所有结点。
知道了左子树和右子树的元素,并且找到了两个子树的根结点,通过同样的方法,在左右子树中分别再找其左右子树,这样递归下去,可以确定唯一的二叉树。
这道题只要求出树的高度,那么我们可以认为,若一个树有左子树或者右子树,则树的高度 + 1。
上面的描述可能不是很准确,举个例子更清楚一点,一棵有9个结点的二叉树
- 先序遍历: 5 2 1 4 3 8 7 6 9
- 中序遍历: 1 2 3 4 5 6 7 8 9
根树
- root = 0;
- pos = 4;
- left = 0;
- right = 9;
根结点为 5;
左子树的根结点为 2
,先序遍历中下标为 root + 1 = 1
;所有结点为 1 2 3 4
,中序遍历中下标范围为 [0, 4)
。
右子树的根结点为 8
,先序遍历中下标为 root + pos - left + 1 = 5
;所有结点为 6 7 8 9
,中序遍历中下标范围为 [5, 9)
。
根树的左子树
- root = 1;
- pos = 1;
- left = 0;
- right = 4;
根结点为 2;
左子树的左子树的根结点为 1
,先序遍历中下标为 root + 1 = 2
;所有结点为 1
,中序遍历中下标范围为 [0, 1)
。
左子树的右子树的根结点为 4
,先序遍历中下标为 root + pos - left + 1 = 3
;所有结点为 3 4
,中序遍历中下标范围为 [2, 4)
。
根树的右左子树
- root = 5;
- pos = 7;
- left = 5;
- right = 9;
根结点为 8;
左子树的左子树的根结点为 7
,先序遍历中下标为 root + 1 = 6
;所有结点为 6 7
,中序遍历中下标范围为 [5, 7)
。
左子树的右子树的根结点为 9
,先序遍历中下标为 root + pos - left + 1 = 8
;所有结点为 9
,中序遍历中下标范围为 [8, 9)
。
左子树的左子树和右子树,右子树的左子树和右子树同理递归下去,就不再继续列出来了。
Code
#include <cstdio>int preorder[1000001]; // 先序遍历int inorder[1000001]; // 中序遍历int height = 0; // 树的高度void findHeight(int root, int left, int right, int h);int main() { int t, n; scanf("%d", &t); while (t--) { height = -1; scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d", preorder + i); for (int i = 0; i < n; ++i) scanf("%d", inorder + i); findHeight(0, 0, n, 0); printf("%d\n", height); } return 0;}void findHeight(int root, int left, int right, int h) { if (left >= right) return; // 判断是否为空树 int pivot = preorder[root]; int pos = left; if (h > height) height = h; // 更新树的高度 while (pos < right && inorder[pos] != pivot) pos++; // 找根结点在中序遍历中的下标 // 递归遍历左子树 if (left < pos) findHeight(root + 1, left, pos, h + 1); // 递归遍历右子树 if (pos + 1 < right) findHeight(root + pos - left + 1, pos + 1, right, h + 1);}
以上所有,如有错误,麻烦指出,我会及时更改的。
- [C++日常小题] 计算二叉查找树的高度
- 1002. 计算二叉查找树的高度
- #sicily#1003.计算二叉查找树的高度
- sicily 计算二叉查找树的高度 期末考试题
- 二叉查找树的结点插入,查找,删除,计算二叉树的高度
- 计算二叉树高度
- 递归计算二叉树的高度
- 计算二叉树的高度递归版本
- 如何计算二叉树的高度。
- 二叉树的遍历、计算、查找
- 给定有序数组,创建高度最小的二叉查找树
- 有序数组创建高度最小的二叉查找树
- 生成高度最小的二叉查找树--CreatMinimalBST
- 判断二叉树是否平衡,计算树的高度
- 计算二叉树的高度和结点数
- 计算二叉树的高度和结点数
- java计算二叉树的高度以及叶节点个数
- 1019_计算二叉树的高度和结点数
- Qt编译错误之out of memory allocating 1073745919 bytes
- win10安装WampServer的步骤(简单地介绍一下)
- WebView第一次加载会白屏,求解决方案
- 1121. Damn Single (25)解题报告
- Android中怎么彻底销毁一个Dialog
- [C++日常小题] 计算二叉查找树的高度
- 浙江中医药大学-Data Structure 笔试期末复习(判断题)
- Java(第一季)基础知识小结
- Android通用流行框架大全
- 蓝牙框架之MultipeerConnectivity框架
- 内存探究记录
- opencv读取摄像头
- 微信Mars——xlog使用全解析
- VC编译器捕获内存访问错误