您的位置:首页 > 编程语言 > C语言/C++

已知先序、中序求后序;已知中序、后序求先序(C++)

2016-07-20 22:11 423 查看

先序中序后序的相互求解问题

一、问题描述

我们知道,二叉树有三种深度优先遍历方法:先序中序以及后序,那么,如何已知其中两种遍历序列,求解第三种遍历序列呢。

其实也没大家想得那么美好哈,已知先序、中序可以确定后序,已知中序,后序可以确定先序,但是已知先序和后序是不能确定中序的。究其原因,其实很简单,因为中序可以确定根节点的左孩子是哪块,右孩子是哪块,就是可以确定父子关系嘛。但是如果知道先序和后序的话,举一个例子,看下面的图:



先序为:1 2;后序为:2 1



先序为:1 2;后序为 2 1
所以,其实已知先序和后序时,是不能确定二叉树的,但是如果含有中序序列,那是可以的。

二、解决方案

我们看下如果手算是怎样的、、举个例子哈,先从先序中序开始:

先序:1 2 3 4 5 6

中序:3 2 4 1 6 5

(1)首先,从先序来看,我们知道1是先序的第一个元素,也是这棵二叉树的根节点。

(2)接着,我们找中序里面对应的1的位置,找到了之后,我们发现3 2 4是在1的左边,也就是说这些都是1的左孩子,先不管这些内部复杂的亲子兄弟关系了。6 5是在1的右边,也就是说这些都是1的右孩子。

(3)在先序中找2 3 4的第一个,是2,在中序里面对应的2左边是3,右边是4,分别是它的左右孩子。

(4)在先序中找6 5,发现第一个是5,在中序里面对应的5地左边是6,右边没有,也就是说,5只有一个左孩子,是6。

(5)由此得到的树为:



已知中序和后序的也很类似,就不详述了。

那么,下面介绍用算法实现的步骤是什么,其实就是简单的递归:

(1)确定根,确定左子树,确定右子树。

(2)在左子树中递归。

(3)在右子树中递归。

(4)打印当前根。

这样看上去似乎很简单,下面看代码好了

三、代码实现

(1)已知先序中序求后序

<pre name="code" class="cpp">struct TreeNode{//每一个节点的属性:左节点、右节点、数据
int data;
TreeNode* left;
TreeNode* right;
};
void BinaryTreeFromOrderings(int *inorder,int *preorder,int length)//中序序列,先序序列,中序中需要寻找的字段长度
{
if(length==0)
return;

TreeNode* node=new TreeNode;//新建一个节点,节点的数据为先序的首个元素
node->data=*preorder;

int rootIndex;//根节点在中序数组中的下标
for(rootIndex=0;rootIndex<length;rootIndex++)
if(inorder[rootIndex]==*preorder)
break;

//后序遍历输出结果
BinaryTreeFromOrderings(inorder,preorder+1,rootIndex);//中序的左边一半长度作为新的需要寻找的字段长度
BinaryTreeFromOrderings(inorder+rootIndex+1,preorder+rootIndex+1,length-(rootIndex+1));//中序的后面一段长度作为需要寻找的字段长度
cout<<node->data;
}

(2)已知中序后序求先序

struct TreeNode{//每一个节点的属性:左节点、右节点、数据
int data;
TreeNode* left;
TreeNode* right;
};
void BinaryTreeFromOrderings(int *inorder,int *lastorder,int length)//中序序列,先序序列,中序中需要寻找的字段长度
{
if(length==0)
return;

TreeNode* node=new TreeNode;
node->data=lastorder+length-1;

int rootindex;
for(rootindex=0;rootindex<length;rootindex++)
if(inorder[rootindex]==node->data)
break;

cout<<node->data<<" ";
BinaryTreeFromOrderings(inorder,lastorder,rootindex);
BinaryTreeFromOrderings(inorder+rootindex+1,lastorder+rootindex,length-(rootindex+1));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: