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


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

    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
     在CODE上查看代码片派生到我的代码片
    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
     在CODE上查看代码片派生到我的代码片
    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
     在CODE上查看代码片派生到我的代码片
    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
     在CODE上查看代码片派生到我的代码片
    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("内存分配失败! ");  
    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("栈为空,不能出栈操作! ");  
    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("栈为空,不能获得栈顶元素值! ");  
    61.         exit(EXIT_FAILURE);  
    62.     }  
    63.     else  
    64.         return s.top->ele;  
    65. }  
    LinkQueue.cpp 链式队列源文件
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    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("内存分配失败! ");  
    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("内存分配失败! ");  
    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("队列为空,不能出队操作! ");  
    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("队列为空,不能获得队头元素! ");  
    72.         exit(EXIT_FAILURE);  
    73.     }  
    74.   
    75.     return q.front->pnext->ele;  
    76. }  

    BiTree.cpp 二叉树源文件
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    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("内存分配失败! ");  
    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("内存分配失败! ");  
    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
     在CODE上查看代码片派生到我的代码片
    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("********二叉树图形******** ");  
    23.     printf("          10 ");  
    24.     printf("         /  \ ");  
    25.     printf("        20   30 ");  
    26.     printf("       / \  / \ ");  
    27.     printf("     40   N N  50 ");  
    28.     printf("    / \       /  \ ");  
    29.     printf("   N  55     60   70 ");  
    30.     printf("     / \    / \  / \ ");  
    31.     printf("   80   N  N  N  N  N ");  
    32.     printf("  / \ ");  
    33.     printf(" N   N ");  
    34.   
    35.     printf("二叉树的深度:%d", DeepBiTree(bt));  
    36.   
    37.     printf(" **********************************");  
    38.   
    39.     printf(" 递归前序遍历:");  
    40.     RePreOrderTraverse(bt);  
    41.     printf(" 递归中序遍历:");  
    42.     ReInOrderTraverse(bt);  
    43.     printf(" 递归后序遍历:");  
    44.     RePostOrderTraverse(bt);  
    45.   
    46.     printf(" **********************************");  
    47.   
    48.     printf(" 非递归前序遍历:");  
    49.     NonRePreOrderTraverse(bt);  
    50.     printf(" 非递归中序遍历:");  
    51.     NonReInOrderTraverse(bt);  
    52.     printf(" 非递归后序遍历:");  
    53.     NonRePostOrderTraverse(bt);  
    54.   
    55.     printf(" **********************************");  
    56.   
    57.     printf(" 非递归层次遍历:");  
    58.     NonReLevelOrderTraverse(bt);  
    59.     printf(" 递归层次遍历:");  
    60.     ReLevelOrderTraverse(bt);  
    61. <span style="white-space:pre">  </span>putchar(' ');  
    [cpp] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. return 0;  
    下面是结果图:
  • 相关阅读:
    Jenkins中构建Testcomplete项目的方法介绍
    抖音批量,批量运营抖音_不要迷恋我_【单月抖音变现7000万】教程
    java 读取 excel 表格内容
    .NET Core 2.1中的分层编译(预览)
    Windows10上使用Linux子系统(WSL)
    swagger上传文件并支持jwt认证
    .NET微服务 容器化.NET应用架构指南(支持.NET Core2)
    用C#编写Linux守护进程
    安装mysql后运行.net程序出错
    2018 你好
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/6037462.html
Copyright © 2020-2023  润新知