c语言二叉树的还原,c语言实现二叉树的恢复

根据二叉树的先序和中序序列恢复二叉树的递归思想是:先根据先序序列的第一个节点建立根节点,然后在中序序列中找到该节点,从而划分处根节点的左右子树的中序序列。接下来再在先序序列中确定左右子树的先序序列,并由左子树的先序序列与中序序列继续递归建立左子树,由左子树的先序序列继续递归建立右子树。

根据二叉树的中序和后序序列恢复二叉树的递归思想是:先根据后序序列的最后一个节点建立根节点,然后在中序序列中找到该节点,从而划分处根节点的左右子树的中序序列。接下来再在先序序列中确定左右子树的先序序列,并由左子树的先序序列与中序序列继续递归建立左子树,由左子树的先序序列继续递归建立右子树。

下面是我的一个实例,供参考,有什么问题,在下方留言,我们一起探讨。

#include

#include

struct BinaryTree

{

int data;

BinaryTree *lchild,*rchild;

};

BinaryTree *CreateTree()

{

BinaryTree *root;

root = (BinaryTree*)malloc(sizeof(BinaryTree));

root = NULL;

return root;

}

//由先序和中序恢复二叉树

void Pre_in_order(char *pred,char *ind,int i,int j,int k,int h,BinaryTree **root)

{

//i,j和k,h分别为当前子树的先序序列和中序序列的下上界

int m;

*root = (BinaryTree*)malloc(sizeof(BinaryTree));

(*root)->data = pred[i];//根据pred数组生成二叉树的根节点

m = k ;//m指向ind数组的中序序列的第一个节点

while(ind[m] != pred[i])//找到根节点在中序序列中的所在位置

{

m++;

}

if(m == k)

{

//根节点是中序序列的第一个节点时则无左子树

(*root)->lchild = NULL;

}

else

{

/*//检查错误

int a1,a2,b1,b2;

a1 = i+1;

a2 = i+m-k;

b1 = k;

b2 = m-1;

printf("\n--1--%d %d %d %d\n",a1,a2,b1,b2);*/

//根据根节点所划分出中序序列的两个部分继续构造左右两颗子树

Pre_in_order(pred,ind,i+1,i+m-k,k,m-1,&(*root)->lchild);

}

if(m == h)

{

//根节点时中序序列的两个部分的最后一个节点时则无右子树

(*root)->rchild = NULL;

}

else

{

检查错误

//int a1,a2,b1,b2;

//a1 = i+m-k+1;

//a2 = j;

//b1 = m+1;

//b2 = h;

//printf("\n--2--%d %d %d %d\n",a1,a2,b1,b2);

//根据根节点所划分出中序序列的两个部分继续构造左右两颗子树

Pre_in_order(pred,ind,i+m-k+1,j,m+1,h,&(*root)->rchild);

}

}

//由中序和后序恢复二叉树

void In_post_order(char *ind,char *post,int l1,int r1,int l2,int r2,BinaryTree **root)

{

//l1,r1和l2,r2分别为当前子树的中序序列和后序序列的下上界

int m;

*root = (BinaryTree*)malloc(sizeof(BinaryTree));

(*root)->data = post[r2];//根据post数组生成二叉树的根节点(后序序列最后一个数)

m = l1;//m指向ind数组的中序序列的第一个节点

while(ind[m] != post[r2])//找到根节点在中序序列中的所在位置

{

m++;

}

//根节点是中序序列的第一个节点时则无左子树

if(m == l1)

{

(*root)->lchild = NULL;

}

else

{

//根据根节点所划分出中序序列的两个部分继续构造左右两颗子树

检查错误

//int a1,a2,b1,b2;

//a1 = l1;

//a2 = m-1;

//b1 = l2;

//b2 = l2+m-l1-1;

//printf("\n--1--%d %d %d %d\n",a1,a2,b1,b2);

In_post_order(ind,post,l1,m-1,l2,l2+m-l1-1,&(*root)->lchild);

}

//根节点时中序序列的两个部分的最后一个节点时则无右子树

if(m == r1)

{

(*root)->rchild = NULL;

}

else

{

/*//检查错误

int a1,a2,b1,b2;

a1 = m+1;

a2 = r1;

b1 = l2+m-l1;

b2 = r2-1;

printf("\n--2--%d %d %d %d\n",a1,a2,b1,b2);

*/

//根据根节点所划分出中序序列的两个部分继续构造左右两颗子树

In_post_order(ind,post,m+1,r1,l2+m-l1,r2-1,&(*root)->rchild);

}

}

void PostTree(BinaryTree *root)

{

if(root)

{

PostTree(root->lchild);

PostTree(root->rchild);

printf("%c ",root->data);

}

}

int main()

{

BinaryTree *tree;

tree = CreateTree();

char pred[10] = {'f','d','b','a','c','e','g','i','h','j'};

char ind[10] = {'a','b','c','d','e','f','g','h','i','j'};

char post[10] = {'a','c','b','e','d','h','j','i','g','f'};

printf("先序和中序恢复结果:\n");

Pre_in_order(pred,ind,0,9,0,9,&tree);

PostTree(tree);

printf("\n\n");

printf("中序和后序恢复结果:\n");

In_post_order(ind,post,0,9,0,9,&tree);

PostTree(tree);

printf("\n");

return 0;

}

运行结果:

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值