前序中序确认二叉树 7-23 还原二叉树(25 分)
7-23 还原二叉树(25 分)
给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
输入格式:
输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。
输出格式:
输出为一个整数,即该二叉树的高度。
输入样例:
9
ABDFGHIEC
FDHGIBEAC
输出样例:
5
代码:
#include<iostream>
#include<string>
using namespace std;
string pre, mid;
int n, num = -1;
int gethigh(int start, int end)
{num++;int i, j;for (i = start; i < end; i++)if (pre[num] == mid[i]) break;if (i == end) return 0;int left = 0, right = 0;if (start < i) left = gethigh(start, i);if (i + 1 < end) right = gethigh(i + 1, end);return left > right ? left + 1 : right + 1;
}
int main()
{cin >> n;cin >> pre;cin >> mid;cout << gethigh(0, n) << endl;
}
要求:根据树的前序和中序确认后序
思路:首先我们要知道中序的意义,拿二叉搜索树来举例,对搜索树进行中序遍历并输出,最后可以得到(由小到大)的有序数组。所以中序其实就相当于给每个元素从左往右标了序号,做过 二叉树横向输出 的朋友应该知道,那题在输出时要知道该节点是从左往右数的第几个,然后才能算需要输出几个‘—’来保持树状。 简而言之,中序就是横向地给节点标记。
其次,我们要知道前序的意义,前序的第一个节点一定是整棵树的根节点。但是对于第二个节点,我们无法知道它是根节点的左子树还是根节点的右子树。
假如前序的第一个节点 在 中序里排在第 5 个位置,而前序的第二个节点 排在中序的第 3 个位置,那么这时候,我们可以判定,第二个节点是第一个节点的左子树。 结合上面的解释应该可以自己理解了,如果还没顿悟的话往下看。 为什么呢? 因为对于第二个节点来说只有两个可能:1.它是第一个节点的左子树 2.它是第一个节点的右子树。我们前面说过,中序是横向地给树标记,第二个节点的位置小于第一个,说明二在一的左边。所以,这时候可以认定,它是一的左子树。
我们可以结合样例来看一看
num | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
pre | A | B | D | F | G | H | I | E | C | |
mid | F | D | H | G | I | B | E | A | C |
对num 从0到8 一一检查:
0:确立根节点A,并在mid中找到A
1:在mid中找到B,如果 B <7,则为A的左子树;如果 B>7,则B为A的右子树。 B为5,A的左子树。
2:在mid中找到D,如果D<5,则为B的左子树,如果5<D<7,则为B的右子树,如果D>7,则为A的右子树。D=1,B的左子树。
3:在mid中找到F,如果F<1,则为D的左子树;
如果1<F<5,则为D的右子树(B的左子树是D,所以显然不可能是B的左子树);
如果5<F<7,则为B的右子树;
如果7<F,则为A的右子树;
4.以此类推。
这样子推有没有觉得特别繁琐?要一个个判断过去多累人啊! 上面的方法主要是给人判断的,如果你要徒手画,就是这个思路。 要用代码实现的话,利用分治的思想,递归分解,把树的规模一步步缩小,就能确认出二叉树了。
上面讲了这么多,其实并不需要把二叉树完整的弄出来,做一个gethigh(int start,int end) 函数就行了。
start,end 是开始与结束的位置。比如确认了A后,左边只要扫描[0,7),右边只要扫描(7,8]。
left = gethigh(…,…) 体现的是 分治的思想
return 取两边大的那个再+1,如果左右都是空,就是返回1.
num放在了外面,确保每次都递进一个搜索。开始做的时候,我把num作为形参,这样导致left之后的num和right的num不同步,然后调试了半天 _(:з」∠)_
最后如果题目要求创建二叉树并后序输出
代码:
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef char Element;
struct Node
{Element data;struct Node *lchild;struct Node *rchild;
};
typedef struct Node BTNode;
typedef struct Node * BTree;
char pre[220];
char mid[220];
BTree creat(char *pre, char *in, int len)
{BTree p = (BTree)malloc(sizeof(BTNode));if (len < 1)return NULL;int i = 0; //每次递归i都初始为0while (in[i] != pre[0])i++; //找出位置p->lchild = creat(pre + 1, in, i);p->rchild = creat(pre + i + 1, in + i + 1, len - i - 1);p->data = pre[0];return p;
}
void post(BTree root)
{if (root){if (root->lchild)post(root->lchild);if (root->rchild)post(root->rchild);cout << root->data;}
}
int main()
{BTree root;cin >> pre;cin >> mid;root = creat(pre, mid, strlen(pre));post(root);cout << endl;
}
转载于:https://www.cnblogs.com/childwang/p/8280274.html
前序中序确认二叉树 7-23 还原二叉树(25 分)相关推荐
- java根据前序和中序建树_(Java实现)二叉树---根据前序、中序、后序数组还原二叉树...
概述在上一篇文章中讲到顺序存储二叉树,一般是用于完全二叉树,通过统一的数学公式可以将数组还原成完全二叉树 而对于普通的二叉树来说,也可以根据前序.中序和后序遍历得到的数组,还原二叉树 还原还原的情况分 ...
- 已知前序中序求层序 c语言递归,二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现...
# re: 二叉树的遍历:前序,中序输出有点问题,但是不知道到怎么修改,想请教各位大神 回复 更多评论 #include"stdio.h" #include"mall ...
- c语言二叉树的还原,由中序遍历和层次遍历还原二叉树。C语言实现
经测,该代码已经修改正确,只需在void BuildTree(char *level,char *inorder,pBiTree T)这里的最后一个变量T改为引用即可.还有一个地方判断调用右子树的地方 ...
- 前序中序、中序后序以及前序后序构造二叉树
文章目录 前序中序 中序后序 前序后序 定义的树节点如下, class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { ...
- 序列化和反序列化二叉树 -----前序,中序,后序,层序
目录 一.序列化和反序列化 1.什么是序列化和反序列化 二.前序遍历 1.序列化 1.问题分析 2.代码实现 2.反序列化 1.问题分析 2.代码实现 三.后序遍历 1.序列化 1.思路分析 2.代码 ...
- 二叉树题目 ----7 前序中序遍历构造二叉树
前序中序遍历构造二叉树 思路 在前序中找根结点 根据根结点 + 中序,分成左右两棵子树 根据子树长度,把前序分成左右两颗子树 递归处理子树 /*** Definition for a binary t ...
- 用前序中序创建二叉树(用中序后序创建二叉树)
定义二叉树结点 比如就拿这个二叉树 前序中序创建 因为前序遍历的顺序是 根 , 左 ,右. 中序的遍历是 左 根 右. 我们会很不好想,但我们可以用前序和中序把上面那个二叉树的遍历一边 前序遍历:AB ...
- C/C++面试题—重建二叉树【前序 + 中序- 重建二叉树 和 后序 + 中序 - 重建二叉树】
题目介绍 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{ ...
- 二叉树前序中序,后序中序,公共最近祖先的实现
二叉树前序中序,后序中序,公共最近祖先的实现 注释中详细介绍了算法,故不再赘述. 无论是前序还是后序,一个节点的左子树和右子树都是可以看做是分开的,有一定规律可循,故可用递归进行实现. #includ ...
最新文章
- Xen 和 KVM 下如何关闭 virbr0
- python安装包-几种Python包的安装方式
- Linux服务器内核参数优化
- 【opencv】边缘高斯模糊(canny+dilate+GaussianBlur)Python实现
- python 一次编辑
- 基于Android5.1的双屏异显分析
- 589-N叉树的前序遍历
- CMake 构建项目Android NDK项目基础知识
- Linux 实操 —— Linux 系统性能分析
- linux etc/init 与etc/init.d的区别
- Python到底能干什么
- Tomcat学习总结(5)——Tomcat容器管理安全的几种验证方式
- 图论(一)—— 基本概念
- 八数码问题【人工智能实验】
- 【洛谷1137】旅行计划【拓扑排序模板】
- 故障分析 | 使用--force批量导入数据导致部分数据丢失的问题
- ast自动扣webpack脚本实战
- 软件测试-------Web(性能测试 / 界面测试 / 兼容性测试 / 安全性测试)
- pyecharts-map世界地图国家中英文对照表
- 基于JAVA汽车出租平台计算机毕业设计源码+数据库+lw文档+系统+部署