根据前序遍历序列和中序遍历序列创建二叉树

悠悠 2022-07-15 01:15 229阅读 0赞
  1. ** 一个前序遍历序列和一个中序遍历序列可以确定一颗唯一的二叉树。**

根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root), 然后在中序序列(InSequence)中查找此根(root), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为根的左子树的中序遍历序列, 后边的序列为根的右子树的中序遍历序列。 设在中序遍历序列(InSequence)根前边有left个元素. 则在前序序列(PreSequence)中, 紧跟着根(root)的left个元素序列(即PreSequence[1…left]) 为根的左子树的前序遍历序列, 在后边的为根的右子树的前序遍历序列.而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为PreSequence[1…left]), 中序序列为InSequence[0…left-1], 分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。每次将根结点的数据赋值,然后不断的递归调用创建左右子树,直到不存在左右子树时函数返回。

二叉树的定义于下:

  1. typedef struct node
  2. {
  3. char data; //结点数据
  4. struct node *Lchild; //左孩子
  5. struct node *Rchild; //右孩子
  6. }tree; //树的结点

完整代码如下:

  1. /*************************************************************************mZ
  2. > Author: FengXin
  3. > Mail: fengxinlinux@gmail.com
  4. > Created Time: 2016年10月27日 星期四 20时01分43秒
  5. ************************************************************************/
  6. #include<stdio.h>
  7. #include<stdlib.h>
  8. #include<string.h>
  9. #include<math.h>
  10. #include<sys/signal.h>
  11. #include<unistd.h>
  12. #include<sys/types.h>
  13. #include<sys/wait.h>
  14. #include<sys/stat.h>
  15. #include<fcntl.h>
  16. typedef struct node
  17. {
  18. char data; //结点数据
  19. struct node *Lchild; //左孩子
  20. struct node *Rchild; //右孩子
  21. }tree; //树的结点
  22. int Lchild_len(char insequence[20],char root_data) //得到左孩子的长度
  23. {
  24. int len=strlen(insequence);
  25. int i=0;
  26. int sum=0; //记录左孩子长度
  27. while(insequence[i]!=root_data)
  28. {
  29. i++;
  30. sum++;
  31. }
  32. return sum;
  33. }
  34. int Rchild_len(char insequence[20],char root_data) //得到右孩子的长度
  35. {
  36. int i=0;
  37. int sum=0; //记录右孩子长度
  38. while(insequence[i]!='\0'&&insequence[i++]!=root_data);
  39. while(insequence[i]!='\0')
  40. {
  41. sum++;
  42. i++;
  43. }
  44. return sum;
  45. }
  46. tree* create_tree(char presequence[20],char insequence[20]) //创建二叉树
  47. {
  48. tree* temp=(tree*)malloc(sizeof(tree)); //创建结点
  49. int L_len,R_len; //储存左右孩子长度
  50. char L_presequence[20],L_insequece[20]; //创建左孩子时传入的左孩子的前序串和中序串
  51. char R_presequence[20],R_insequece[20]; //创建右孩子时传入的右孩子的前序串和中序串
  52. L_presequence[0]=L_insequece[0]=R_presequence[0]=R_insequece[0]='\0';
  53. if(strlen(presequence)!=0&&strlen(insequence)!=0) //传入的序列串非空
  54. {
  55. temp->data=presequence[0]; //根结点数据赋值
  56. L_len=Lchild_len(insequence,presequence[0]); //获得孩子的长度
  57. R_len=Rchild_len(insequence,presequence[0]);
  58. strncpy(L_presequence,presequence+1,L_len); //得到要递归创建孩子时要传入的前序遍历串和中序遍历串
  59. *(L_presequence+L_len)='\0'; //字符串末尾加上'\0'
  60. strncpy(R_presequence,presequence+L_len+1,R_len);
  61. *(R_presequence+R_len)='\0';
  62. strncpy(L_insequece,insequence,L_len);
  63. *(L_insequece+L_len)='\0';
  64. strncpy(R_insequece,insequence+L_len+1,R_len);
  65. *(R_insequece+R_len)='\0';
  66. temp->Lchild=create_tree(L_presequence,L_insequece); //递归创建左子树
  67. temp->Rchild=create_tree(R_presequence,R_insequece); //递归创建右子树
  68. return temp; //返回结点地址
  69. }
  70. else //若根结点无孩子,则返回空指针
  71. {
  72. return NULL;
  73. }
  74. }
  75. void postorder(tree *root) //后序遍历树输出
  76. {
  77. if(root!=NULL)
  78. {
  79. postorder(root->Lchild);
  80. postorder(root->Rchild);
  81. printf("%3c",root->data);
  82. }
  83. else
  84. return;
  85. }
  86. int main()
  87. {
  88. char presequence[20]; //存先序序列
  89. char insequence[20]; //存中序序列
  90. tree *root;
  91. printf("请输入先序序列\n");
  92. scanf("%s",presequence);
  93. printf("请输入中序序列\n");
  94. scanf("%s",insequence);
  95. root=create_tree(presequence,insequence);
  96. printf("创建二叉树成功\n");
  97. printf("后序遍历输出为:\n");
  98. postorder(root);
  99. printf("\n");
  100. }

发表评论

表情:
评论列表 (有 0 条评论,229人围观)

还没有评论,来说两句吧...

相关阅读