前中序遍历已知求后序遍历(树的补充)

已知前序遍历和中序遍历是否能画出二叉树?

已知前序遍历和中序遍历可以画出二叉树,或者已知中序遍历和后序遍历也可以画出二叉树;已知前序遍历和后序遍历无法画出二叉树;
假设父节点时Fa,左节点是L,右节点是R,那么三种遍历方式是:

前序遍历:Fa->L->R
中序遍历:L->Fa->R
后序遍历:L->R->Fa

所以根据其遍历方式可知根据三种遍历结果具有不同的特性:

a、前序遍历的第一个肯定是根节点,后序遍历中的最后一个肯定是根节点;

b、知道根节点(前序或后序),可根据中序遍历知道其左子树和右子树;

c、每次对当前节点作为根节点分析可以确定一个点的位置,递归可得整棵二叉树;

前序和中序已知画树例子:

前序顺序:BCDAEGFIH

中序顺序:DCEAGBIFH

1、根据a可知B为根节点,根据c可知:DCEAG为左子树,IFH为右子树;


2、对左子树(递归),前序是CDAEG,中序是DCEAG;同理根据a可知C是子树的根节点,根据c可知:D是左子树,EAG是右子树;

3、同样递归思想,前序是AEG知A是子树的根节点,中序是EAG知左子树是E右子树是G

4、回到右子树,同理前序是FIH,中序是IFH,可知子树的根节点是F,左子树是I,右子树是H;

一棵二叉树就画完了,同样的道理,已知中序和后序遍历的时候同样的也可以画出二叉树;最主要思想:是通过中序遍历得知二叉树的左子树和右子树,通过前序遍历或者或许遍历知道每一次的根节点,通过递归的思想一步一步画出节点;

根据以上分析的代码实现:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef struct anode* Node;
typedef struct anode
{
	Node left;
	Node right;
	char element;
}Anode;

//通过前序中序遍历构建一棵二叉树并且输出其后序遍历
Node BuildTree_From_PreAndIn(char* in, char* pre, int lenth)
{
	if (lenth == 0)return NULL;
	Node node = new Anode;
	node->element = *pre;                                  //每次递归进入该函数时,即此子树的根节点的元素值;
	int root = 0;                                          //最初始时根节点的为pre[0],root编号为0;
	for (; root < lenth; root++)
	{
		if (in[root] == *pre)break;                        //找到此时根节点在中序遍历中的位置编号root;
	}
	node->left = BuildTree_From_PreAndIn(in, pre + 1, root);       //左子树在除原来的根节点(类似pre[0])的子序列中即从pre+1处往后,长度是中序遍历中根节点位置编号左边字符串长度即root;
	node->right = BuildTree_From_PreAndIn(in + root + 1, pre + root + 1, lenth - (root + 1));//右子树在左子树之后(类似pre[0]),长度是中序遍历中根节点位置编号右边字符串长度lenth-(root+1);
	cout << node->element << endl;
	return node;
}

int main()
{
	char* pre = "GDAFEMHZ";
	char* in = "ADEFGHMZ";
	BuildTree_From_PreAndIn(in, pre, 8);
	return 0;
}

主要思想时递归使用,不是很清楚可以设置断点深入理解其过程;

参考博客:http://blog.csdn.net/feliciafay/article/details/6816871

PS感想:在看关于这个前序中序网上博客时,看到这是面试笔试题且博主没写出来;算法就像一根硬骨头,all of us are dogs,lucky or stupid,depending on yourself.今天学的不仅仅只是为了小小的算法期末考,今后总会有遇到的时候,骨头啃的越久,啃掉的越多,就越lucky,当然这需要时间;

posted @ 2017-12-27 20:45  heihuifei  阅读(1031)  评论(0编辑  收藏  举报