- 思想:
以下图二叉树为例进行思路演示
先序:(根、左、右)a b d e c f g
中序:(左、根、右)d b e a f c g
后序:(左、右、根)d e b f g c a
- 先序+中序恢复
1)前序第一个为根a,找中序内和先序第一个相等的根位置
2)中序遍历将左右子树隔开,左子树个数为3。先序遍历中,从根a后面找3个
3)递归划分左子树: 先序遍历可知b是左子树的根,从中序遍历中找到根b,b左边是左子树,右边是右子树
重复3)步骤,找到右子树的根c,在中序遍历中将c的左子树f,右子树g找到。
- 中序+后序恢复
1)后序中最后一个字符a为根,在中序中找到根a的位置
2)在中序中根a的左边为左子树,右边为右子树
3) 再从后序中找到左子树根b,右子树的根c,然后在中序中根左边为左子树,右边为右子树。递归重复进行查找。
- 代码:
typedef struct node
{
char value;//当前节点值
struct node* left;//指向当前节点左孩子指针
struct node* right;//指向当前节点右孩子指针
}Node;
typedef struct tree
{
Node* root;
}Tree;
void InitTree(Tree* t)
{
t->root = NULL;
}
//用先序字符串和中序字符串恢复二叉树
Node* Create(const char* vlr,const char* lvr,int n)
{//函数参数:vlr: 先序遍历,lvr: 中序遍历n: 当前字符串个数
//字符串遍历完毕,即为到达叶子节点,无左右子树
if (n == 0)
return NULL;
//还有字符串
else
{
int k = 0;
while (vlr[0] != lvr[k])
{
k++;
}
Node* root = (Node*)malloc(sizeof(Node));
root->value = vlr[0];
//左子树
root->left = Create(vlr + 1, lvr, k);
//右子树
root->right = Create(vlr + 1+k, lvr+k+1, n-k-1);
return root;
}
}
//后序
void PostOrder(node* root)
{
if (root != NULL)
{
PostOrder(root->left);
PostOrder(root->right);
printf("%c", root->value);
}
}
int main()
{
const char* vlr = "abdecfg";//先序
const char* lvr = "dbeafcg";//中序
Tree t;
InitTree(&t);
int n = strlen(vlr);
t.root = Create(vlr, lvr, n);
PostOrder(t.root);//后序遍历输出验证一下
printf("\n");
}
- 运行结果: