当前位置:   article > 正文

数据结构 - 二叉树的遍历

二叉树的遍历

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程

二叉树的遍历

N:访问根结点,L:遍历根结点的左子树,R:遍历根结点的右子树。

给定一棵二叉树的前序遍历序列和中序遍历序列可以惟一确定一棵二叉树。

二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。

深度优先遍历二叉树

1. 中序遍历(LNR)的递归算法:

若二叉树为空,则算法结束;否则:

中序遍历根结点的左子树;

访问根结点;

中序遍历根结点的右子树。

2. 前序遍历(NLR)的递归算法:

若二叉树为空,则算法结束,否则:

访问根结点;

前序遍历根结点的左子树;

前序遍历根结点的右子树。

3. 后序遍历(LRN)的递归算法:

若二叉树为空,则算法结束,否则:

后序遍历根结点的左子树;

后序遍历根结点的右子树;

访问根结点。

非递归深度优先遍历二叉树

栈是实现递归最常用的结构,利用一个栈来记下尚待遍历的结点或子树,以备以后访问,可以将递归的深度优先遍历改为非递归的算法。

1. 非递归前序遍历:遇到一个结点,就访问该结点,并把此结点推入栈中,然后下降去遍历它的左子树。遍历完它的左子树后,从栈顶托出这个结点,并按照它的右链接指示的地址再去遍历该结点的右子树结构。

2. 非递归中序遍历:遇到一个结点,就把它推入栈中,并去遍历它的左子树。遍历完左子树后,从栈顶托出这个结点并访问之,然后按照它的右链接指示的地址再去遍历该结点的右子树。

3. 非递归后序遍历:遇到一个结点,把它推入栈中,遍历它的左子树。遍历结束后,还不能马上访问处于栈顶的该结点,而是要再按照它的右链接结构指示的地址去遍历该结点的右子树。遍历完右子树后才能从栈顶托出该结点并访问之。另外,还需要给栈中的每个元素加上一个特征位,以便当从栈顶托出一个结点时区别是从栈顶元素左边回来的(则要继续遍历右子树),还是从右边回来的(则该结点的左、右子树均已遍历)。特征为Left表示已进入该结点的左子树,将从左边回来;特征为Right表示已进入该结点的右子树,将从右边回来。

非递归广度优先遍历二叉树

非递归广度优先遍历二叉树(层序遍历)是用队列来实现的。从二叉树的第一层(根结点)开始,自上至下逐层遍历;在同一层中,按照从左到右的顺序对结点逐一访问。

按照从根结点至叶结点、从左子树至右子树的次序访问二叉树的结点。算法如下:

1. 初始化一个队列,并把根结点入队列;

2. 当队列为非空时,循环执行步骤3到步骤5,否则执行6;

3. 出队列取得一个结点,访问该结点;

4. 若该结点的左子树为非空,则将该结点的左子树入队列;

5. 若该结点的右子树为非空,则将该结点的右子树入队列;

6. 结束。

  1. /*
  2. * Binary Tree Breadth-First Traverse - by Chimomo
  3. */
  4. #include <iostream>
  5. #define _OK 1
  6. #define _ERROR 0
  7. using namespace std;
  8. // Define node element type in binary tree.
  9. typedef char Element;
  10. // Binary tree node.
  11. typedef struct BTNode {
  12. Element data;
  13. BTNode *lChild, *rChild; // Define left, right subtree.
  14. } BTNode, *BTree;
  15. // Define node element type in queue. (The node element type in queue is the pointer to binary tree node)
  16. typedef BTNode *QElementType;
  17. typedef int status;
  18. // We need use queue to perform level traverse. So, define queue first.
  19. typedef struct QNode {
  20. QElementType data;
  21. QNode *next;
  22. } QNode, *QueuePtr;
  23. // Definition of queue.
  24. typedef struct {
  25. QueuePtr front;
  26. QueuePtr rear;
  27. } LinkQueue;
  28. status InitQueue(LinkQueue &Q) {
  29. Q.front = NULL;
  30. Q.rear = NULL;
  31. return _OK;
  32. }
  33. bool IsEmpty(LinkQueue Q) {
  34. return Q.front == NULL;
  35. }
  36. /**
  37. * Enqueue.
  38. * @param Q The queue.
  39. * @param e The queue element.
  40. * @return 1 for ok, 0 for error.
  41. */
  42. status EnQueue(LinkQueue &Q, QElementType e) {
  43. // Construct queue node.
  44. QNode *ptrNode = (QNode *) malloc(sizeof(QNode));
  45. if (!ptrNode) {
  46. return _ERROR;
  47. }
  48. ptrNode->data = e;
  49. ptrNode->next = NULL;
  50. if (IsEmpty(Q)) {
  51. Q.front = Q.rear = ptrNode;
  52. return _OK;
  53. }
  54. Q.rear->next = ptrNode;
  55. Q.rear = ptrNode;
  56. return _OK;
  57. }
  58. /**
  59. * Dequeue.
  60. * @param Q The queue.
  61. * @param e The queue element.
  62. * @return 1 for ok, 0 for error.
  63. */
  64. status DeQueue(LinkQueue &Q, QElementType &e) {
  65. if (IsEmpty(Q)) {
  66. return _ERROR;
  67. }
  68. QNode *tempPtr = Q.front;
  69. e = tempPtr->data;
  70. Q.front = tempPtr->next;
  71. free(tempPtr);
  72. return _OK;
  73. }
  74. /**
  75. * Create binary tree.
  76. * @param T The binary tree address.
  77. * @return 1 for success, 0 for fail.
  78. */
  79. int CreateBTree(BTree &T) {
  80. char ch;
  81. cout << "Please input a character:" << endl;
  82. cin >> ch;
  83. if (ch == '#') {
  84. T = NULL;
  85. } else {
  86. // Allocate memory for new node.
  87. if (!(T = (BTNode *) malloc(sizeof(BTNode)))) {
  88. return 0; // Allocation fails.
  89. }
  90. T->data = ch;
  91. // Create left subtree.
  92. CreateBTree(T->lChild);
  93. // Create right subtree.
  94. CreateBTree(T->rChild);
  95. }
  96. return 1;
  97. }
  98. void VisitBTNode(BTNode *BT) {
  99. cout << BT->data << " ";
  100. }
  101. void VisitQNode(QNode *Q) {
  102. VisitBTNode(Q->data);
  103. }
  104. /**
  105. * Breadth-first traverse.
  106. * @param T The binary tree.
  107. */
  108. void LevelTraverse(BTree T) {
  109. QElementType e;
  110. LinkQueue Q;
  111. InitQueue(Q);
  112. EnQueue(Q, T);
  113. while (!IsEmpty(Q)) {
  114. VisitQNode(Q.front);
  115. if (Q.front->data->lChild != NULL) {
  116. EnQueue(Q, Q.front->data->lChild);
  117. }
  118. if (Q.front->data->rChild != NULL) {
  119. EnQueue(Q, Q.front->data->rChild);
  120. }
  121. DeQueue(Q, e);
  122. }
  123. }
  124. int main() {
  125. BTree T;
  126. CreateBTree(T);
  127. cout << "Breadth-first traverse: ";
  128. LevelTraverse(T);
  129. return 0;
  130. }
  131. // Output:
  132. /*
  133. Please input a character:
  134. 1
  135. 1
  136. Please input a character:
  137. 2
  138. 2
  139. Please input a character:
  140. 3
  141. 3
  142. Please input a character:
  143. 4
  144. 4
  145. Please input a character:
  146. 5
  147. 5
  148. Please input a character:
  149. 6
  150. 6
  151. Please input a character:
  152. #
  153. #
  154. Please input a character:
  155. #
  156. #
  157. Please input a character:
  158. #
  159. #
  160. Please input a character:
  161. #
  162. #
  163. Please input a character:
  164. #
  165. #
  166. Please input a character:
  167. #
  168. #
  169. Please input a character:
  170. #
  171. #
  172. Breadth-first traverse: 1 2 3 4 5 6
  173. */

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/615234
推荐阅读
相关标签
  

闽ICP备14008679号