二叉树遍历算法——包含递归前中后序和层次,非递归前中后序和层次遍历共八种

Posted 专注it

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树遍历算法——包含递归前中后序和层次,非递归前中后序和层次遍历共八种相关的知识,希望对你有一定的参考价值。

首先,要感谢网上的参考资料。

 

  1. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha)
  2. http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻)
  3. http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace)

 

 

       二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化、新建、以及遍历。这里主要是为了学习二叉树的遍历算法,我总结后,写了八种二叉树的遍历算法,分别是:

 

 

      1.递归先序遍历
      2.递归中序遍历
      3.递归后序遍历
      4.非递归先序遍历(单栈辅助)
      5.非递归中序遍历(单栈辅助)
      6.非递归后序遍历(单栈辅助)
      7.递归层次遍历
      8.非递归层次遍历(队列辅助)
      当然,这里还要用到栈和队列,博客中以前有提到过(链式的栈和链式队列),其实还可以用顺序栈和顺序队列的(博客中后面将补上这块)。下面直接上代码:
 
LinkStack.h 链式栈头文件
[cpp] view plain copy
 技术分享技术分享
  1. #ifndef _LINK_STACK_H_H  
  2. #define _LINK_STACK_H_H  
  3.   
  4. #include "BiTree.h"  
  5.   
  6. typedef pBiTree LStackEle;   
  7.   
  8. typedef struct LSNODE  
  9. {  
  10.     LStackEle ele;  
  11.     struct LSNODE *pnext;  
  12. }LSNode, *pLSNode;  
  13.   
  14. typedef struct LSTACK  
  15. {  
  16.     pLSNode top;  
  17. }LStack, *pLStack;  
  18.   
  19. //栈初始化  
  20. void InitLinkStack(LStack &s);  
  21.   
  22. //入栈  
  23. void PushLinkStack(LStack &s, LStackEle ele);  
  24.   
  25. //出栈  
  26. void PopLinkStack(LStack &s, LStackEle &ele);  
  27.   
  28. //判断栈是否为空  
  29. bool IsemptyLinkStack(LStack s);  
  30.   
  31. //获得栈顶值  
  32. LStackEle GetTopLinkStack(LStack s);  
  33.   
  34. #endif  
LinkQueue.h 链式队列头文件
[html] view plain copy
 技术分享技术分享
  1. #ifndef _LINK_QUEUE_H_H  
  2. #define _LINK_QUEUE_H_H  
  3.   
  4. #include "BiTree.h"  
  5.   
  6. typedef pBiTree LQueueEle;  
  7.   
  8. typedef struct LQNODE  
  9. {  
  10.     LQueueEle ele;  
  11.     struct LQNODE *pnext;  
  12. }LQNode, *pLQNode;  
  13.   
  14. typedef struct LQUEUE  
  15. {  
  16.     pLQNode rear;  
  17.     pLQNode front;  
  18. }LQueue, *pLQueue;  
  19.   
  20. //初始化队列  
  21. void InitLinkQueue(LQueue &q);  
  22.   
  23. //入队  
  24. void EnLinkQueue(LQueue &q, LQueueEle ele);  
  25.   
  26. //出队  
  27. void DeLinkQueue(LQueue &q, LQueueEle &ele);  
  28.   
  29. //判断队列是否为空  
  30. bool IsemptyLinkQueue(LQueue q);  
  31.   
  32. //获得队头元素值  
  33. LQueueEle GetFrontLinkQueue(LQueue q);  
  34.   
  35. #endif  

BiTree.h 二叉树头文件
[cpp] view plain copy
 技术分享技术分享
  1. #ifndef _BITREE_H_H  
  2. #define _BITREE_H_H  
  3.   
  4. typedef struct BINODE  
  5. {  
  6.     int ele;  
  7.     struct BINODE *plchild;  
  8.     struct BINODE *prchild;  
  9. }BiNode, *pBiTree;  
  10.   
  11. //初始化二叉树(含根节点)  
  12. void InitBiTree(pBiTree &bt, int ele);  
  13.   
  14. //创建二叉树节点  
  15. BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele);  
  16.   
  17. //插入左子二叉树  
  18. void InsertLChild(pBiTree parent, pBiTree lchild);  
  19.   
  20. //插入右子二叉树  
  21. void InsertRChild(pBiTree parent, pBiTree rchild);  
  22.   
  23. //计算二叉树的深度  
  24. int DeepBiTree(pBiTree bt);  
  25.   
  26. //递归先序遍历  
  27. void RePreOrderTraverse(pBiTree bt);   
  28.   
  29. //递归中序遍历  
  30. void ReInOrderTraverse(pBiTree bt);  
  31.   
  32. //递归后序遍历  
  33. void RePostOrderTraverse(pBiTree bt);  
  34.   
  35. //非递归先序遍历二  
  36. void NonRePreOrderTraverse(pBiTree bt);  
  37.   
  38. //非递归中序遍历  
  39. void NonReInOrderTraverse(pBiTree bt);  
  40.   
  41. //非递归后序遍历  
  42. void NonRePostOrderTraverse(pBiTree bt);  
  43.   
  44. //非递归层次遍历  
  45. void NonReLevelOrderTraverse(pBiTree bt);  
  46.   
  47. //递归层次遍历  
  48. void ReLevelOrderTraverse(pBiTree bt);  
  49.   
  50. void PrintLevelNode(pBiTree bt, int level);  
  51.   
  52. #endif  

LinkStack.cpp 链式栈源文件
[html] view plain copy
 技术分享技术分享
  1. #include "LinkStack.h"  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4.   
  5. //栈初始化  
  6. void InitLinkStack(LStack &s)  
  7. {  
  8.     s.top= NULL;  
  9. }  
  10.   
  11. //入栈  
  12. void PushLinkStack(LStack &s, LStackEle ele)  
  13. {  
  14.     pLSNode pnew = (pLSNode)malloc(sizeof(LSNode));  
  15.     if (pnew == NULL)  
  16.     {  
  17.         printf("内存分配失败!\n");  
  18.         exit(EXIT_FAILURE);  
  19.     }  
  20.   
  21.     pnew->ele = ele;  
  22.     pnew->pnext = s.top;  
  23.     s.top = pnew;  
  24. }  
  25.   
  26. //出栈  
  27. void PopLinkStack(LStack &s, LStackEle &ele)  
  28. {  
  29.     pLSNode pt = NULL;  
  30.     if (IsemptyLinkStack(s))  
  31.     {  
  32.         printf("栈为空,不能出栈操作!\n");  
  33.         exit(EXIT_FAILURE);  
  34.     }  
  35.     else  
  36.     {  
  37.         ele = s.top->ele;  
  38.         pt = s.top;  
  39.         s.top = pt->pnext;  
  40.         free(pt);  
  41.         pt = NULL;  
  42.     }  
  43.   
  44. }  
  45.   
  46. //判断栈是否为空  
  47. bool IsemptyLinkStack(LStack s)  
  48. {  
  49.     if (s.top == NULL)  
  50.         return true;  
  51.     else  
  52.         return false;  
  53. }  
  54.   
  55. //获得栈顶元素  
  56. LStackEle GetTop(LStack s)  
  57. {  
  58.     if (IsemptyLinkStack(s))  
  59.     {  
  60.         printf("栈为空,不能获得栈顶元素值!\n");  
  61.         exit(EXIT_FAILURE);  
  62.     }  
  63.     else  
  64.         return s.top->ele;  
  65. }  
LinkQueue.cpp 链式队列源文件
[cpp] view plain copy
 技术分享技术分享
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include "LinkQueue.h"  
  4.   
  5. //初始化队列  
  6. void InitLinkQueue(LQueue &q)  
  7. {  
  8.     q.front = (pLQNode)malloc(sizeof(LQNode));  
  9.     if (q.front == NULL)  
  10.     {  
  11.         printf("内存分配失败!\n");  
  12.         exit(EXIT_FAILURE);  
  13.     }  
  14.   
  15.     q.rear = q.front;  
  16. }  
  17.   
  18. //入队  
  19. void EnLinkQueue(LQueue &q, LQueueEle ele)  
  20. {  
  21.     pLQNode pnew = (pLQNode)malloc(sizeof(LQNODE));  
  22.     if (pnew == NULL)  
  23.     {  
  24.         printf("内存分配失败!\n");  
  25.         exit(EXIT_FAILURE);  
  26.     }  
  27.   
  28.     pnew->ele = ele;  
  29.     pnew->pnext = NULL;  
  30.     q.rear->pnext = pnew;  
  31.     q.rear = pnew;  
  32. }  
  33.   
  34. //出队  
  35. void DeLinkQueue(LQueue &q, LQueueEle &ele)  
  36. {  
  37.     pLQNode pt = NULL;  
  38.   
  39.     if (IsemptyLinkQueue(q))  
  40.     {  
  41.         printf("队列为空,不能出队操作!\n");  
  42.         exit(EXIT_FAILURE);  
  43.     }  
  44.   
  45.     ele = q.front->pnext->ele;  
  46.     pt = q.front->pnext;  
  47.     q.front->pnext = pt->pnext;  
  48.     free(pt);  
  49. /* 
  50.     pt是最后一个节点时,释放完了以后,尾指针指向的 
  51.     是随机内存,所以让它和头指针指向同一个地址。 
  52. */  
  53.     if (q.front->pnext == NULL)        
  54.         q.rear = q.front;  
  55. }  
  56.   
  57. //判断队列是否为空  
  58. bool IsemptyLinkQueue(LQueue q)  
  59. {  
  60.     if (q.front == q.rear)  
  61.         return true;  
  62.     else  
  63.         return false;  
  64. }  
  65.   
  66. //获得队头元素  
  67. LQueueEle GetFrontLinkQueue(LQueue q)  
  68. {  
  69.     if (IsemptyLinkQueue(q))  
  70.     {  
  71.         printf("队列为空,不能获得队头元素!\n");  
  72.         exit(EXIT_FAILURE);  
  73.     }  
  74.   
  75.     return q.front->pnext->ele;  
  76. }  

BiTree.cpp 二叉树源文件
[cpp] view plain copy
 技术分享技术分享
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include "BiTree.h"  
  4. #include "LinkStack.h"  
  5. #include "LinkQueue.h"  
  6.   
  7.   
  8. //初始化二叉树(含根节点)  
  9. void InitBiTree(pBiTree &bt, int ele)  
  10. {  
  11.     bt = (BiNode *)malloc(sizeof(BiNode));  
  12.     if (bt == NULL)  
  13.     {  
  14.         printf("内存分配失败!\n");  
  15.         exit(EXIT_FAILURE);  
  16.     }  
  17.   
  18.     bt->ele = ele;  
  19.     bt->plchild = NULL;  
  20.     bt->prchild = NULL;  
  21. }  
  22.   
  23. //创建二叉树节点  
  24. BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele)  
  25. {  
  26.     BiNode *pnew = (BiNode *)malloc(sizeof(BiNode));  
  27.     if (pnew == NULL)  
  28.     {  
  29.         printf("内存分配失败!\n");  
  30.         exit(EXIT_FAILURE);  
  31.     }  
  32.   
  33.     pnew->ele = ele;  
  34.     pnew->plchild = lchild;  
  35.     pnew->prchild = rchild;  
  36.   
  37.     return pnew;  
  38. }  
  39.   
  40. //插入左子二叉树  
  41. void InsertLChild(pBiTree parent, pBiTree lchild)  
  42. {  
  43.     parent->plchild = lchild;  
  44. }  
  45.   
  46. //插入右子二叉树  
  47. void InsertRChild(pBiTree parent, pBiTree rchild)  
  48. {  
  49.     parent->prchild = rchild;  
  50. }  
  51.   
  52. //用递归的方法计算二叉树的深度  
  53. int DeepBiTree(pBiTree bt)  
  54. {  
  55.     int ldeep = 0, rdeep = 0;  
  56.   
  57.     if (bt)  
  58.     {  
  59.         ldeep = DeepBiTree(bt->plchild);  
  60.         rdeep = DeepBiTree(bt->prchild);  
  61.         return (ldeep > rdeep ? ldeep : rdeep) + 1;  
  62.     }  
  63.     else  
  64.         return 0;  
  65. }  
  66.   
  67. //(一)递归先序遍历  
  68. void RePreOrderTraverse(pBiTree bt)  
  69. {  
  70.     if(bt != NULL)  
  71.     {  
  72.         printf("%d ", bt->ele);  
  73.         RePreOrderTraverse(bt->plchild);  
  74.         RePreOrderTraverse(bt->prchild);  
  75.     }  
  76. }  
  77.   
  78. //(二)递归中序遍历  
  79. void ReInOrderTraverse(pBiTree bt)  
  80. {  
  81.     if(bt != NULL)  
  82.     {  
  83.         ReInOrderTraverse(bt->plchild);  
  84.         printf("%d ", bt->ele);  
  85.         ReInOrderTraverse(bt->prchild);  
  86.     }  
  87. }  
  88.   
  89. //(三)递归后序遍历  
  90. void RePostOrderTraverse(pBiTree bt)  
  91. {  
  92.     if(bt != NULL)  
  93.     {  
  94.         RePostOrderTraverse(bt->plchild);  
  95.         RePostOrderTraverse(bt->prchild);  
  96.         printf("%d ", bt->ele);  
  97.     }  
  98. }  
  99.   
  100. //(四)非递归先序遍历  
  101. void NonRePreOrderTraverse(pBiTree bt)  
  102. {  
  103.     LStack s;  
  104.     InitLinkStack(s);  
  105.   
  106.     while (bt != NULL || !IsemptyLinkStack(s))  
  107.     {  
  108.         while ( bt != NULL)  
  109.         {  
  110.             printf("%d ", bt->ele);  
  111.             PushLinkStack(s, bt);  
  112.             bt = bt->plchild;  
  113.         }  
  114.   
  115.         if (!IsemptyLinkStack(s))  
  116.         {  
  117.             PopLinkStack(s, bt);  
  118.             bt = bt->prchild;  
  119.         }  
  120.     }  
  121. }  
  122.   
  123. //(五)非递归中序遍历  
  124. void NonReInOrderTraverse(pBiTree bt)  
  125. {  
  126.     LStack s;  
  127.     InitLinkStack(s);  
  128.   
  129.     while (bt != NULL || !IsemptyLinkStack(s))  
  130.     {  
  131.         while (bt != NULL)  
  132.         {  
  133.             PushLinkStack(s, bt);  
  134.             bt = bt->plchild;  
  135.         }  
  136.   
  137.         if (!IsemptyLinkStack(s))  
  138.         {  
  139.             PopLinkStack(s, bt);  
  140.             printf("%d ", bt->ele);  
  141.             bt = bt->prchild;  
  142.         }  
  143.     }  
  144. }  
  145.   
  146. //(六)非递归后序遍历  
  147. void NonRePostOrderTraverse(pBiTree bt)  
  148. {  
  149.     LStack s;  
  150.     InitLinkStack(s);  
  151.     BiNode * pt = NULL;  
  152.   
  153.     while (bt != NULL || !IsemptyLinkStack(s))  
  154.     {  
  155.         while (bt != NULL)  
  156.         {  
  157.             PushLinkStack(s, bt);  
  158.             bt = bt->plchild;  
  159.         }  
  160.   
  161.         if (!IsemptyLinkStack(s))  
  162.         {  
  163.             PopLinkStack(s, bt);  
  164.   
  165.             if (bt->prchild == NULL || bt->prchild == pt)  
  166.             {  
  167.                 printf("%d ", bt->ele);  
  168.                 pt = bt;  
  169.                 bt = NULL;  
  170.             }  
  171.             else  
  172.             {  
  173.                 PushLinkStack(s, bt);  
  174.                 bt = bt->prchild;  
  175.             }  
  176.         }  
  177.     }  
  178. }  
  179.   
  180. //(七)非递归层次遍历  
  181. void NonReLevelOrderTraverse(pBiTree bt)  
  182. {  
  183.     LQueue q;  
  184.     InitLinkQueue(q);  
  185.     BiNode *pt = NULL;  
  186.   
  187.     if (bt != NULL)  
  188.     {  
  189.         EnLinkQueue(q, bt);  
  190.   
  191.         while (!IsemptyLinkQueue(q))  
  192.         {  
  193.             DeLinkQueue(q, pt);  
  194.             printf("%d ", pt->ele);  
  195.             if (pt->plchild != NULL)  
  196.                 EnLinkQueue(q, pt->plchild);  
  197.             if (pt->prchild != NULL)  
  198.                 EnLinkQueue(q, pt->prchild);  
  199.         }  
  200.     }  
  201. }  
  202.   
  203. //(八)递归层级遍历  
  204. void ReLevelOrderTraverse(pBiTree bt)  
  205. {  
  206.     int i, deep;  
  207.   
  208.     if (bt != NULL)  
  209.     {  
  210.         deep = DeepBiTree(bt);  
  211.         for(i=1; i<deep+1; i++)  
  212.             PrintLevelNode(bt, i);  
  213.     }  
  214. }  
  215.   
  216. void PrintLevelNode(pBiTree bt, int level)  
  217. {  
  218.     if (bt != NULL && level > 0)  
  219.     {  
  220.         if (level == 1)  
  221.             printf("%d ", bt->ele);  
  222.         PrintLevelNode(bt->plchild, level - 1);  
  223.         PrintLevelNode(bt->prchild, level - 1);  
  224.     }  
  225. }  

main.cpp 测试程序源文件
[cpp] view plain copy
 技术分享技术分享
  1. #include <stdio.h>  
  2. #include "BiTree.h"  
  3. #include "LinkStack.h"  
  4. #include "LinkQueue.h"  
  5.   
  6. int main(void)  
  7. {  
  8.     //二叉树测试代码  
  9.     pBiTree bt;  
  10.     InitBiTree(bt, 10);  
  11.   
  12.     pBiTree lchild = CreateBiTreeNode(CreateBiTreeNode(NULL,   
  13.         CreateBiTreeNode(CreateBiTreeNode(NULL, NULL, 80),   
  14.         NULL, 55), 40), NULL, 20);  
  15.     InsertLChild(bt, lchild);  
  16.   
  17.     pBiTree rchild = CreateBiTreeNode(NULL, CreateBiTreeNode(  
  18.         CreateBiTreeNode(NULL, NULL, 60),   
  19.         CreateBiTreeNode(NULL, NULL, 70), 50), 30);  
  20.     InsertRChild(bt, rchild);  
  21.   
  22.     printf("********二叉树图形********\n");  
  23.     printf("          10\n");  
  24.     printf("         /  \\\n");  
  25.     printf("        20   30\n");  
  26.     printf("       / \\  / \\\n");  
  27.     printf("     40   N N  50\n");  
  28.     printf("    / \\       /  \\\n");  
  29.     printf("   N  55     60   70\n");  
  30.     printf("     / \\    / \\  / \\\n");  
  31.     printf("   80   N  N  N  N  N\n");  
  32.     printf("  / \\\n");  
  33.     printf(" N   N\n");  
  34.   
  35.     printf("二叉树的深度:%d", DeepBiTree(bt));  
  36.   
  37.     printf("\n**********************************");  
  38.   
  39.     printf("\n递归前序遍历:");  
  40.     RePreOrderTraverse(bt);  
  41.     printf("\n递归中序遍历:");  
  42.     ReInOrderTraverse(bt);  
  43.     printf("\n递归后序遍历:");  
  44.     RePostOrderTraverse(bt);  
  45.   
  46.     printf("\n**********************************");  
  47.   
  48.     printf("\n非递归前序遍历:");  
  49.     NonRePreOrderTraverse(bt);  
  50.     printf("\n非递归中序遍历:");  
  51.     NonReInOrderTraverse(bt);  
  52.     printf("\n非递归后序遍历:");  
  53.     NonRePostOrderTraverse(bt);  
  54.   
  55.     printf("\n**********************************");  
  56.   
  57.     printf("\n非递归层次遍历:");  
  58.     NonReLevelOrderTraverse(bt);  
  59.     printf("\n递归层次遍历:");  
  60.     ReLevelOrderTraverse(bt);  
  61. <span style="white-space:pre">  </span>putchar(‘\n‘);  
[cpp] view plain copy
 技术分享技术分享
  1. return 0;  
下面是结果图:











以上是关于二叉树遍历算法——包含递归前中后序和层次,非递归前中后序和层次遍历共八种的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的前中后序递归和非递归遍历操作代码

二叉树的遍历(前中后序,递归和非递归)

二叉树前中序非递归遍历

二叉树的前中后序遍历的递归与非递归算法模版

二叉树的中序和后序遍历的非递归实现

二叉树的前中后序非递归法