问题描述
在一个二叉树中,前序遍历结果为:ABDGCEFH, 中序遍历结果为DGBAECHF,求后序遍历结果二叉树的遍历
前序遍历方式:根左右
中序遍历方式:左根右
后序遍历方式:左右根所以,前序遍历中的第一个结点就是根结点,然后再在中序遍历序列中找到这个值所在的位置,则中序遍历序列中该值的左边部分即为需还原二叉树的左子树部分中序遍历结果,同理,该值的右边部分即为二叉树右子树中序遍历结果。然后再在前序遍历中找到对应在中序遍历中找到的左、右子树部分的元素位置,再分别对左、右子树部分找根节点,依次递归,即可还原二叉树。
简单表述如下:
输入前序ABDGCEFH,中序DGBAECHF,可以得出
A为该二叉树的根节点
1: BDG为该二叉树左子树的前序
2: DGB为该二叉树左子树的中序根据1和2可以构建一棵左子树
3: CEFH为该二叉树右子树的前序
4: ECHF为该二叉树右子树的中序
根据3和4可以构建一个右子树上面的命名在代码可以看见
以上描述参考文章:http://blog.youkuaiyun.com/hinyunsin/article/details/6315502
代码实现
/******************************************************************
Author tmw
date:2018-3-15
*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**定义二叉树数据结构**/
typedef struct BiTreeNode
{
char data;
struct BiTreeNode* left;
struct BiTreeNode* right;
}BiTreeNode,*BiTree;
/**在中序遍历中找根节点所在下标--找到:返回下标值;没找到,返回-1**/
int find_root_index( char* mid_travel, int mid_travel_left, int mid_travel_right, char root_node )
{
int i;
if( !mid_travel || mid_travel_left<0 || mid_travel_right>=strlen(mid_travel) || mid_travel_left>mid_travel_right)
return -1;
for( i=mid_travel_left;i<=mid_travel_right;i++ )
if( mid_travel[i] == root_node )
return i;
return -1;
}
/**找到根节点**/
BiTree getRoot( char* pre_travel, char* mid_travel, int pre_t_left, int pre_t_right, int mid_t_left, int mid_t_right )
{
//参数合法性检查
if( !pre_travel || !mid_travel )
return NULL;
if( pre_t_left<0 || pre_t_right>strlen(pre_travel)-1 || pre_t_left>pre_t_right )
return NULL;
if( mid_t_left<0 || mid_t_right>strlen(mid_travel)-1 || mid_t_left>mid_t_right )
return NULL;
//通过前序找到根节点,并对它进行初始化
char rootElem = pre_travel[pre_t_left];
BiTree root;
root = (BiTree)malloc(sizeof(BiTreeNode));
root->data = rootElem;
root->left = NULL;
root->right = NULL;
//找根节点在中序中的下标
int root_index = find_root_index( mid_travel,mid_t_left,mid_t_right,rootElem );
if( root_index<0 )
return NULL;
//递归求左子树部分的根节点
root->left = getRoot(pre_travel,mid_travel,pre_t_left+1,pre_t_left+root_index-mid_t_left,mid_t_left,root_index-1);
//递归求右子树部分的根节点
root->right = getRoot(pre_travel,mid_travel,pre_t_left+root_index-mid_t_left+1,pre_t_right,root_index+1,mid_t_right);
return root;
}
//创建二叉树
BiTree CreateBiTree( char* pre_travel, char* mid_travel )
{
if( !pre_travel || !mid_travel )
return NULL;
return getRoot(pre_travel,mid_travel,0,strlen(pre_travel)-1,0,strlen(mid_travel)-1);
}
/**后序遍历**/
void back_travel( BiTree T )
{
if( !T )
return;
back_travel( T->left );
back_travel( T->right );
printf("%c ",T->data);
}
/**测试代码**/
int main()
{
BiTree T;
// T = (BiTree)malloc(sizeof(BiTreeNode));
printf("测试代码\n");
char* pre_travel = "ABDGCEFH";
char* mid_travel = "DGBAECHF";
printf("给定的前序遍历为:%s\n",pre_travel);
printf("给定的中序遍历为:%s\n",mid_travel);
printf("构造出的二叉树后序遍历为:\n");
T = CreateBiTree( pre_travel, mid_travel );
back_travel( T );
return 0;
}
结果