二叉树遍历(非递归版)

谁践踏了优雅 2022-06-16 05:16 309阅读 0赞

问题描述:
以一定的方式输入数据(本文是以先序遍历的方式输入),程序根据数据进行解析,创建二叉树,然后对二叉树进行操作,主要操作包括以下几种:

  1. 求二叉树的高度
  2. 先序遍历二叉树
  3. 中序遍历二叉树
  4. 后序遍历二叉树
  5. 层序遍历二叉树

先序遍历: 根节点->左子树->右子树
中序遍历: 左子树->根节点->右子树
先序遍历: 左子树->右子树->根节点
层序遍历: 第一层(根节点)->第二层->第三次->….

PS:

  1. 大家可以清楚的看到,先序,中序和后序是相对于根节点而言的
  2. 非递归版代码描述起来比递归版略显复杂
  3. 递归版本可以查看我的另外一篇文章:
    http://blog.csdn.net/yi_ming_he/article/details/71248881

以下面的例子进行说明:
这里写图片描述

如图所示,根据上面的遍历顺序,我们可以得到以下遍历结果:
先序遍历: a b d h e c f g
中序遍历: h d b e a f c g
后序遍历: h d e b f g c a
层序遍历: a b c d e f g h

参考代码:

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <string.h>
  4. #include <queue>
  5. #include <stack>
  6. #define MAXNODE 1024
  7. char str[MAXNODE];
  8. typedef struct BiTNode
  9. {
  10. char data;
  11. struct BiTNode* lchild;
  12. struct BiTNode* rchild;
  13. }BiTNode, *Bitree;
  14. void CreateBiTree(Bitree& T)
  15. {
  16. //这是根据先序遍历建立的一棵树
  17. scanf_s("%s", str, MAXNODE);
  18. Bitree tempT, tempQ;
  19. T = (Bitree)malloc(sizeof(BiTNode));
  20. T->data = str[0];
  21. T->lchild = NULL;
  22. T->rchild = NULL;
  23. std::stack<Bitree>st;
  24. st.push(T);
  25. for (int i = 1; i < (int)strlen(str); i++)
  26. {
  27. if (str[i] == '#')
  28. {
  29. tempT = st.top();
  30. st.pop();
  31. if (NULL == tempT->lchild)
  32. i++;
  33. }
  34. else
  35. {
  36. tempT = st.top();
  37. tempQ = (Bitree)malloc(sizeof(BiTNode));
  38. tempQ->data = str[i];
  39. tempQ->lchild = NULL;
  40. tempQ->rchild = NULL;
  41. if (tempT->lchild)
  42. {
  43. tempT->rchild = tempQ;
  44. st.pop();
  45. }
  46. else
  47. tempT->lchild = tempQ;
  48. st.push(tempQ);
  49. }
  50. }
  51. }
  52. void PreOrderTraverseByNonRecursion(Bitree T)
  53. {
  54. if (!T)
  55. return;
  56. std::stack<std::pair<Bitree, bool>> st;
  57. st.push(std::make_pair(T, false));
  58. bool bVisited = false;
  59. while (!st.empty())
  60. {
  61. T = st.top().first;
  62. bVisited = st.top().second;
  63. st.pop();
  64. if (!T)
  65. continue;
  66. if (bVisited)
  67. printf("%c ", T->data);
  68. else
  69. {
  70. st.push(std::make_pair(T->rchild, false));
  71. st.push(std::make_pair(T->lchild, false));
  72. st.push(std::make_pair(T, true));
  73. }
  74. }
  75. }
  76. void InOrderTraverseByNonRecursion(Bitree T)
  77. {
  78. if (!T)
  79. return;
  80. std::stack<std::pair<Bitree, bool>> st;
  81. st.push(std::make_pair(T, false));
  82. bool bVisited = false;
  83. while (!st.empty())
  84. {
  85. T = st.top().first;
  86. bVisited = st.top().second;
  87. st.pop();
  88. if (!T)
  89. continue;
  90. if (bVisited)
  91. printf("%c ", T->data);
  92. else
  93. {
  94. st.push(std::make_pair(T->rchild, false));
  95. st.push(std::make_pair(T, true));
  96. st.push(std::make_pair(T->lchild, false));
  97. }
  98. }
  99. }
  100. void PostOrderTraverseByNonRecursion(Bitree T)
  101. {
  102. if (!T)
  103. return;
  104. std::stack<std::pair<Bitree, bool>> st;
  105. st.push(std::make_pair(T, false));
  106. bool bVisited = false;
  107. while (!st.empty())
  108. {
  109. T = st.top().first;
  110. bVisited = st.top().second;
  111. st.pop();
  112. if (!T)
  113. continue;
  114. if (bVisited)
  115. printf("%c ", T->data);
  116. else
  117. {
  118. st.push(std::make_pair(T, true));
  119. st.push(std::make_pair(T->rchild, false));
  120. st.push(std::make_pair(T->lchild, false));
  121. }
  122. }
  123. }
  124. int GetBiTreeHeightByNonRecursion(Bitree T)
  125. {
  126. if (!T)
  127. return 0;
  128. int nVisitedNodeCount = 0;//已经访问过的节点数
  129. int nPushQueueNumber = 1;//记录入队列的节点的最大序号
  130. int nLevelMaxNumber = 1;//记录每一次的最大的序号
  131. int nTreeHeight = 0;//记录树的高度
  132. std::queue<Bitree> Q;
  133. Q.push(T);
  134. while (!Q.empty())
  135. {
  136. T = Q.front();
  137. Q.pop();
  138. nVisitedNodeCount++;
  139. if (T->lchild)
  140. {
  141. Q.push(T->lchild);
  142. nPushQueueNumber++;
  143. }
  144. if (T->rchild)
  145. {
  146. Q.push(T->rchild);
  147. nPushQueueNumber++;
  148. }
  149. if (nVisitedNodeCount == nLevelMaxNumber)
  150. {
  151. nTreeHeight++;
  152. nLevelMaxNumber = nPushQueueNumber;
  153. }
  154. }
  155. return nTreeHeight;
  156. }
  157. void LevelOrderTraverseByNonRecursion(Bitree T)
  158. {
  159. if (!T)
  160. return;
  161. std::queue<Bitree> Q;
  162. Q.push(T);
  163. while (!Q.empty())
  164. {
  165. T = Q.front();
  166. Q.pop();
  167. printf("%c ", T->data);
  168. if (T->lchild)
  169. Q.push(T->lchild);
  170. if (T->rchild)
  171. Q.push(T->rchild);
  172. }
  173. }
  174. int main()
  175. {
  176. Bitree T;
  177. CreateBiTree(T);
  178. printf("树的高度是: %d\n", GetBiTreeHeightByNonRecursion(T));
  179. printf("先序遍历(非递归):\n");
  180. PreOrderTraverseByNonRecursion(T);
  181. printf("\n");
  182. printf("中序遍历(非递归):\n");
  183. InOrderTraverseByNonRecursion(T);
  184. printf("\n");
  185. printf("后序遍历(非递归):\n");
  186. PostOrderTraverseByNonRecursion(T);
  187. printf("\n");
  188. printf("层序遍历(非递归):\n");
  189. LevelOrderTraverseByNonRecursion(T);
  190. printf("\n");
  191. return 0;
  192. }

运行结果:
这里写图片描述

发表评论

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

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

相关阅读

    相关

    问题描述: 以一定的方式输入数据(本文是以先序遍历的方式输入),程序根据数据进行解析,创建二叉树,然后对二叉树进行操作,主要操作包括以下几种: 1. 求二叉树的高度 2