根据中序和层次遍历序列,构造二叉树

大致了解了一下。层次遍历的同时,用中序序列求出子树的下标范围,并标记在子树根结点上。利用左右孩子为空的特殊情况,一层一层构造,直至叶子结点。

代码如下,思路详见注释:


 
 
  1. #include<stdio.h>
  2. #include<iostream>
  3. #include<queue>
  4. using namespace std;
  5. typedef struct Bitree{
  6. char data;
  7. struct Bitree *lchild;
  8. struct Bitree *rchild;
  9. }Bitree,*Bi;
  10. typedef struct{
  11. int lel; //指向当前处理的元素在层次序列中的位置
  12. int low,high; //中序序列的上下界
  13. Bi parent; //层次序列中当前结点的双亲结点指针
  14. int lr; //判断左右子树,1为左,2为右
  15. }Sq;
  16. void preorder(Bi p);
  17. void Creat(Bi &bt,char lev[],char in[],int n)
  18. {
  19. Sq q;
  20. queue <Sq> Q;
  21. if(n< 1)
  22. bt= NULL; //二叉树为空
  23. else
  24. {
  25. int i,s;
  26. i=s= 0; //s指向层次序列中当前处理的元素,i用来寻找当前处理的元素在中序序列中的位置
  27. bt= new Bitree;
  28. bt->data=lev[ 0];
  29. bt->lchild=bt->rchild= NULL;
  30. while(in[i]!=lev[ 0])
  31. i++;
  32. if(i== 0 && i==n -1) return ; //只有一个根节点
  33. if(i== 0) //没有左子树
  34. {
  35. bt->lchild= NULL;
  36. q.lel=++s; q.low=i+ 1; q.high=n -1; q.lr= 2; q.parent=bt;
  37. Q.push(q);
  38. }
  39. else if(i==n -1) //没有右子树
  40. {
  41. bt->rchild= NULL;
  42. q.lel=++s; q.low= 0; q.high=i -1; q.lr= 1; q.parent=bt;
  43. Q.push(q);
  44. }
  45. else
  46. {
  47. q.lel=++s; q.low= 0; q.high=i -1; q.lr= 1; q.parent=bt;
  48. Q.push(q);
  49. q.lel=++s; q.low=i+ 1; q.high=n -1; q.lr= 2; q.parent=bt;
  50. Q.push(q);
  51. }
  52. while(!Q.empty())
  53. {
  54. q=Q.front(); Q.pop();
  55. Bi fat=q.parent;
  56. i=q.low;
  57. while(in[i]!=lev[q.lel])
  58. i++;
  59. Bi p= new Bitree;
  60. p->data=lev[q.lel];
  61. p->lchild=p->rchild= NULL;
  62. if(q.lr== 1)
  63. fat->lchild=p;
  64. else
  65. fat->rchild=p;
  66. if(i==q.low && i==q.high) //叶子结点,无孩子
  67. {
  68. p->lchild=p->rchild= NULL;
  69. continue;
  70. }
  71. else if(i==q.low) //没有左孩子
  72. {
  73. p->lchild= NULL;
  74. q.lel=++s; q.low=i+ 1; q.parent=p; q.lr= 2;
  75. Q.push(q);
  76. }
  77. else if(i==q.high) //没有右孩子
  78. {
  79. p->rchild= NULL;
  80. q.lel=++s; q.high=i -1; q.parent=p; q.lr= 1;
  81. Q.push(q);
  82. }
  83. else
  84. {
  85. int high=q.high; //备份一下
  86. q.lel=++s; q.high=i -1; q.parent=p; q.lr= 1;
  87. Q.push(q);
  88. q.lel=++s; q.low=i+ 1; q.high=high; q.parent=p; q.lr= 2;
  89. Q.push(q);
  90. }
  91. }
  92. }
  93. }
  94. int main()
  95. {
  96. int n;
  97. Bitree *B;
  98. char in[ 50],lev[ 50];
  99. printf( "请输入结点个数\n");
  100. cin>>n;
  101. printf( "请输入中序遍历和层次遍历\n");
  102. getchar();
  103. gets(in); gets(lev);
  104. Creat(B,lev,in,n);
  105. printf( "构造完成,输出先序序列\n");
  106. preorder(B);
  107. return 0;
  108. }
  109. void preorder(Bi p)
  110. {
  111. if(p)
  112. {
  113. printf( "%c ",p->data);
  114. preorder(p->lchild);
  115. preorder(p->rchild);
  116. }
  117. }


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值