根据树的前序遍历、中序遍历、后序遍历中的两种遍历求第三种遍历结果
来源:互联网 发布:淘宝新店防骗 编辑:程序博客网 时间:2024/05/29 18:13
学过数据结构,都知道二叉树有四种遍历手段,前序遍历、中序遍历、后序遍历以及层序遍历,而前三种遍历存在较强的关联,即:知道中序遍历及另外两种遍历中的一种时,可以求第三种,简单的讲就是根据中序遍历和前序遍历、后序遍历中的一种,可以求第三种。是不是有些绕了,自己慢慢理解吧!我们这里要讲一下实现代码。遇见这种问题,我听说好像可以用栈来实现,但是今天要说的是通过建树来实现的。分为两种情况:1、知道前序遍历和中序遍历,求后序遍历。 这个相对比较简单,因为我们可以通过查找根结点在中序遍历的位置来对两种遍历序列切割,分成子序列,这样通过递归可以实现建树,并且在递归函数尾加上一条输出语句即可实现后序遍历。2、知道后序遍历和中序遍历,求前序遍历。 这个就有些难了,对三种遍历没有教深入理解的人是无法理解透这个算法的,其实和前边的算法大致一样,只是有些许的细节差别,我们同样是要查找根结点在中序遍历中的位置,但是我们不能用同样的手段分隔,我们知道,中序遍历,根结点的左边的都是左子树,右边的都是右子树,而后序遍历中的根结点在尾部,所以想要分隔必须对中序遍历进行以根结点为中心左右分割(不留下根结点),对后序遍历进行的分割要保证前半段的长度和中序遍历的前半段长度一致,后半段去除根结点的部分,这样分成了两段同样也是左右子树,另外输出语句也要提前,因为这是前序遍历,所以输出语句需要在递归函数调用自身前就进行输出。
大致的思路就是这样,先看第一种的代码(代码C++):
#include <iostream>#include <fstream>#include <string>struct TreeNode{ struct TreeNode* left; struct TreeNode* right; char elem;};void BinaryTreeFromOrderings(char* inorder, char* preorder, int length){ if(length == 0) { //cout<<"invalid length"; return; } TreeNode* node = new TreeNode;//Noice that [new] should be written out. node->elem = *preorder; int rootIndex = 0; for(;rootIndex < length; rootIndex++) { if(inorder[rootIndex] == *preorder) break; } //Left BinaryTreeFromOrderings(inorder, preorder +1, rootIndex); //Right BinaryTreeFromOrderings(inorder + rootIndex + 1, preorder + rootIndex + 1, length - (rootIndex + 1)); cout<<node->elem<<endl; return;}int main(int argc, char* argv[]){ printf("Hello World!\n"); char* pr="GDAFEMHZ"; char* in="ADEFGHMZ"; BinaryTreeFromOrderings(in, pr, 8); printf("\n"); return 0;}
接着,是第二种情况的代码(代码C):
#include <stdio.h>#include <string.h>#include <stdlib.h>typedef char TElemType;#define MAX_TREE_SIZE 100typedef struct BiTNode //结点结构{ TElemType data; //结点数据 struct BiTNode *lchild, *rchild; //左右孩子指针} BiTNode, *BiTree;//建树并前序遍历void BinaryTreeFromOrderings(char *mid, char *last, int len){ //长度为0则返回空 if (len == 0) { return ; } BiTree node = (BiTree)malloc(sizeof(BiTNode)); //分配结点空间 node->data = last[len - 1]; //mid中寻找根结点 int rootIndex = 0; for (; rootIndex < len; rootIndex++) { if (mid[rootIndex] == last[len - 1]) { break; } } //前序遍历,则在建一个节点打印一次 printf("%c", node->data); //Left BinaryTreeFromOrderings(mid, last, rootIndex); //Right BinaryTreeFromOrderings(mid + rootIndex + 1, last + rootIndex, len - (rootIndex + 1)); //后段为右子树 return ;}int main(int argc, const char * argv[]){ char mid[100], last[100], len; scanf("%s %s", mid, last); len = (int)strlen(mid); BinaryTreeFromOrderings(mid, last, len); printf("\n"); return 0;}
这两种情况算法都是一样的,差别就在于序列切割的位置不同,切割的方式也不同,也就是存在细节上的一些问题需要多注意才是,其他的就没有什么了,对了,要多学学怎么用指针,没有过硬的指针使用基础,会很不好做的,毕竟是数据结构中的知识,��。
0 0
- 根据树的前序遍历、中序遍历、后序遍历中的两种遍历求第三种遍历结果
- 前序遍历,中序遍历和后序遍历 & 已知两种遍历,求第三种遍历
- 根据前序遍历和中序遍历的结果确定后序遍历
- 二叉树问题-根据前序遍历结果和中序遍历结果得出后序遍历结果
- 根据前序遍历中序遍历求二叉树
- 树-根据前序、中序遍历求后续遍历
- 根据树的前序遍历和中序遍历构造树,输出后序遍历
- 根据中序遍历和后序遍历求二叉树的先序遍历
- 二叉树的遍历(前序 中序 后序)和已知两种遍历顺序求另外一种遍历顺序(含实例)
- 树 前序遍历,中序遍历,后序遍历
- 题目1078:二叉树遍历(根据前序和中序遍历结果,获得后序遍历)
- 树的前序遍历,中序遍历,后序遍历,层次(广度)遍历
- 二叉树的遍历(前序遍历、中序遍历、后序遍历)
- 二叉树的遍历 前序遍历 中序遍历 后序遍历
- 二叉树的遍历:前序遍历、中序遍历和后序遍历
- 非递归实现前序遍历+中序遍历得到后序遍历的结果
- 二叉树的遍历方法及根据前/中(后/中)序遍历求后(前)序遍历的代码实现
- 根据中序遍历和前序遍历输出后序遍历,自己的代码
- 一种查看chromium代码两任何两个版本之间修改Log的方法
- 模版--两圆相交部分面积
- 如何获取到Hadoop集群的个数
- SpringMvc - 用户注册自动生成默认头像深色底/浅色字工具类实现
- ELK实战-Logstash:监控日志文件
- 根据树的前序遍历、中序遍历、后序遍历中的两种遍历求第三种遍历结果
- io
- mapreduce原理全剖析map+shuffle+reducer 全部过程
- Shell - 14
- 23. 客户默认选项(Default Customer Options)
- 安卓开发MyEclipse【服务器创建】
- Friends(并查集)
- ueditor自制上传在ie9中的bug
- JVM:垃圾回收机制和调优手段