根据后序和中序或前序和中序求二叉树这个算法我理解起来有些障碍,学了许久才弄明白是怎么一回事。
大体流程就是以后序(或前序)为获取根节点的序列,以中序为主体寻取节点的左右子树以达到建树的目的。
分析由后序和中序序列还原二叉树的样例:
后序:2 3 1 5 7 6 4
中序:1 2 3 4 5 6 7
由后序遍历二叉树的规则知,最后一个遍历的节点为根节点
故,取根节点4,到中序序列中寻找该节点。该节点前为根节点的左子树,后面为根节点的右子树。
即:123 4 567
然后本着先建右子树的理念,取后序倒数第二个元素(即右子树的根节点)6,来成为右子树的根节点。
再到中序中寻找右子树根节点的位置,来确定右子树根节点的左右子树,如果左右子节点皆为叶子节点则设其左右子节点指向NULL。
以此类推建立其他节点。
下附代码:
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int N;
typedef struct BiTree
{
int Data;
struct BiTree* left, *right;
}BiTree;
BiTree* CreatTree(int K1[], int K2[], int start, int ends, int &index)
{
int mid = K1[index];
int i;
for(i = ends; i >= start; i--)
{
if(mid == K2[i])
{
break;
}
}
BiTree *root = (BiTree*)malloc(sizeof(BiTree));
root->Data = mid, root->right = NULL, root->left = NULL;
if(i + 1 <= ends)
{
root->right = CreatTree(K1, K2, i + 1, ends, --index);
}
if(i - 1 >= start)
{
root->left = CreatTree(K1, K2, start, i - 1, --index);
}
return root;
}
void Preorder(BiTree* key)
{
if(key)
{
printf(" %d", key->Data);
Preorder(key->left);
Preorder(key->right);
}
}
int main()
{
scanf("%d", &N);
int K1[100], K2[100];// K1 hou xu K2 zheng xu
int i;
for(i = 0; i < N; i++)
{
int n;
scanf("%d", &n);
K1[i] = n;
}
for(i = 0; i < N; i++)
{
int n;
scanf("%d", &n);
K2[i] = n;
}
BiTree *One;
int k = N - 1;
One = CreatTree(K1, K2, 0, N - 1, k);//建立二叉树
printf("Preorder:");
Preorder(One);//遍历二叉树
printf("\n");
return 0;
}