二叉树的先序遍历,中序遍历,后序遍历和层序遍历

分手后的思念是犯贱 2022-04-15 03:23 451阅读 0赞

1.二叉树的构成

任何一个非空的二叉树都由根结点、左子树、右子树这三部分构成。

树的遍历是访问树中每个结点仅一次的过程。可将遍历看作是把所有的结点放在一条线上(即对树进行线性化的处理)。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDc1OTE0_size_16_color_FFFFFF_t_70

2.二叉树的遍历

先序遍历: DLR 中序遍历:LDR 后序遍历:LRD 层序遍历:一层一层从左向右依次输出

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDc1OTE0_size_16_color_FFFFFF_t_70 1

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDc1OTE0_size_16_color_FFFFFF_t_70 2

20181120233946677.png

3.实现代码:

先序遍历采用递归的方式:

  • 若二叉树非空
  • (1)访问根结点;
  • (2)先序遍历左子树;
  • (3)先序遍历右子树
  1. //先序遍历
  2. Status PreOrderTraverse(BiTree T){
  3. if(T)
  4. {
  5. visit(T);
  6. PreOrderTraverse(T->lchild);
  7. PreOrderTraverse(T->rchild);
  8. }
  9. return ok;
  10. }

中序遍历:

  • 若二叉树非空
  • (1)中序遍历左子树;
  • (2)访问根结点;
  • (3)中序遍历右子树;
  1. //中序遍历
  2. Status InOrderTraverse(BiTree T)
  3. {
  4. if(T)
  5. {
  6. InOrderTraverse(T->lchild );
  7. visit(T);
  8. InOrderTraverse(T->rchild );
  9. }
  10. return ok;
  11. }

后序遍历:

  • 若二叉树非空
  • (1)后序遍历左子树
  • (2)后序遍历右子树
  • (3)访问根结点D
  1. //后序遍历
  2. Status PostOrderTraverse(BiTree T)
  3. {
  4. if(T)
  5. {
  6. PostOrderTraverse(T->lchild );
  7. PostOrderTraverse(T->rchild );
  8. visit(T);
  9. }
  10. return ok;
  11. }

层序遍历:

n先根,后子树;先左子树,后右子树。

利用队列实现二叉树的层序遍历:

  • 构造一个空队列;
  • 树根结点入队列;
  • while (队列不空) {
  • 令队头结点X出队列;
  • 访问结点X;
  • 若X的左孩子、右孩子结点存在,则依次加入队列;
  • }
  1. //层序遍历
  2. Status levelOrder(BiTree T)
  3. {
  4. LinkQuene Q;BiTree A;
  5. InitQuene( Q);
  6. EnQuene(Q,T);
  7. while(!EmptyQue(Q))
  8. {
  9. A=Q.front->next->data;
  10. visit(A);
  11. if(A->lchild!=NULL)
  12. EnQuene(Q,A->lchild);
  13. if(A->rchild!=NULL)
  14. EnQuene(Q,A->rchild);
  15. DeQuene(Q);
  16. }

4.二叉树的存储结构:

typedef struct BiNode{
TElemType data;
struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

5.创建二叉树:

  1. Status CreateBiTree(BiTree &T)
  2. {
  3. char ch;
  4. scanf("%c",&ch);
  5. if(ch=='.') T=NULL;
  6. else{
  7. T=(BiTree)malloc(sizeof(BiNode));
  8. if(!T) exit(overflow);
  9. T->data=ch;
  10. CreateBiTree(T->lchild);
  11. CreateBiTree(T->rchild);
  12. }
  13. return ok;
  14. }

6.测试代码—主函数

  1. int main(){
  2. BiTree T;
  3. printf("以先序遍历序列输入创建二叉树:\n");
  4. CreateBiTree(T);
  5. printf("依次输出先序,中序,后序及层序遍历序列:\n") ;
  6. PreOrderTraverse(T);
  7. printf("\n");
  8. InOrderTraverse(T);
  9. printf("\n");
  10. PostOrderTraverse(T);
  11. printf("\n");
  12. levelOrder(T);
  13. printf("\n");
  14. system("pause");
  15. return 0;
  16. }

7.当然,对于层序遍历中的有关队列的一些基本函数没有细化,故在此将完整代码写出供大家参考:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<malloc.h>
  4. #define ok 1
  5. #define error 0
  6. #define true 1
  7. #define false 0
  8. #define overflow -2
  9. typedef int Status;
  10. typedef char TElemType;
  11. //定义二叉树结构
  12. typedef struct BiNode{
  13. TElemType data;
  14. struct BiNode *lchild,*rchild;
  15. }BiNode,*BiTree;
  16. //打印函数
  17. void visit(BiTree p)
  18. {
  19. printf("%c ",p->data);
  20. }
  21. //队列结构,用于层序遍历
  22. typedef BiTree QElemType;
  23. typedef struct QNode{
  24. QElemType data;
  25. struct QNode *next;
  26. }QNode,*QuenePtr;
  27. typedef struct {
  28. QuenePtr front;
  29. QuenePtr rear;
  30. }LinkQuene;
  31. //初始化队列
  32. Status InitQuene(LinkQuene &Q)
  33. {
  34. Q.front=Q.rear=(QuenePtr)malloc(sizeof(QNode));
  35. if(!Q.front)
  36. exit(overflow);
  37. Q.front->next=NULL;
  38. return ok;
  39. }
  40. //判断队列是否为空
  41. Status EmptyQue(LinkQuene Q)
  42. {
  43. if(Q.front==Q.rear)
  44. return true;
  45. else
  46. return false;
  47. }
  48. //入队
  49. Status EnQuene(LinkQuene &Q,QElemType e)
  50. {
  51. QuenePtr p;
  52. p=(QuenePtr)malloc(sizeof(QNode));
  53. if(!p)
  54. exit(overflow);
  55. p->data=e;
  56. p->next=NULL;
  57. Q.rear->next=p;
  58. Q.rear=p;
  59. return ok;
  60. }
  61. //出队
  62. Status DeQuene(LinkQuene &Q)
  63. {
  64. QuenePtr p;
  65. if(Q.front==Q.rear)
  66. return error;
  67. p=Q.front->next;
  68. Q.front->next=p->next;
  69. if(Q.rear==p)
  70. Q.rear=Q.front;
  71. free(p);
  72. return ok;
  73. }
  74. //创建二叉树
  75. Status CreateBiTree(BiTree &T)
  76. {
  77. char ch;
  78. scanf("%c",&ch);
  79. if(ch=='.') T=NULL;
  80. else{
  81. T=(BiTree)malloc(sizeof(BiNode));
  82. if(!T) exit(overflow);
  83. T->data=ch;
  84. CreateBiTree(T->lchild);
  85. CreateBiTree(T->rchild);
  86. }
  87. return ok;
  88. }
  89. //先序遍历
  90. Status PreOrderTraverse(BiTree T){
  91. if(T)
  92. {
  93. visit(T);
  94. PreOrderTraverse(T->lchild);
  95. PreOrderTraverse(T->rchild);
  96. }
  97. return ok;
  98. }
  99. //中序遍历
  100. Status InOrderTraverse(BiTree T)
  101. {
  102. if(T)
  103. {
  104. InOrderTraverse(T->lchild );
  105. visit(T);
  106. InOrderTraverse(T->rchild );
  107. }
  108. return ok;
  109. }
  110. //后序遍历
  111. Status PostOrderTraverse(BiTree T)
  112. {
  113. if(T)
  114. {
  115. PostOrderTraverse(T->lchild );
  116. PostOrderTraverse(T->rchild );
  117. visit(T);
  118. }
  119. return ok;
  120. }
  121. //层序遍历
  122. Status levelOrder(BiTree T)
  123. {
  124. LinkQuene Q;BiTree A;
  125. InitQuene( Q);
  126. EnQuene(Q,T);
  127. while(!EmptyQue(Q))
  128. {
  129. A=Q.front->next->data;
  130. visit(A);
  131. if(A->lchild!=NULL)
  132. EnQuene(Q,A->lchild);
  133. if(A->rchild!=NULL)
  134. EnQuene(Q,A->rchild);
  135. DeQuene(Q);
  136. }
  137. return ok;
  138. }
  139. int main(){
  140. BiTree T;
  141. printf("以先序遍历序列输入创建二叉树:\n");
  142. CreateBiTree(T);
  143. printf("依次输出先序,中序,后序及层序遍历序列:\n") ;
  144. PreOrderTraverse(T);
  145. printf("\n");
  146. InOrderTraverse(T);
  147. printf("\n");
  148. PostOrderTraverse(T);
  149. printf("\n");
  150. levelOrder(T);
  151. printf("\n");
  152. system("pause");
  153. return 0;
  154. }

8.程序截图

此范例既是上面所举例子,可自行核对。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDc1OTE0_size_16_color_FFFFFF_t_70 3

发表评论

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

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

相关阅读