• 二叉树的先序,中序,后序,层次,递归,非递归遍历


         关于二叉树的遍历,递归遍历的话,就只要不断的递归就够啦,而非递归的话就需要用到栈和队列了,然而栈和队列也是我自己写的吧,就算是锻炼了一下自己对数据结构课的掌握吧,而非递归后序遍历二叉树参考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。

    一、先序遍历二叉树

       1.递归遍历

        每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。

     1 /*二叉树递归先序遍历*/
     2 void PreTraverseTree1(TreeNode * T)
     3 {
     4     if(T)
     5     {
     6         printf("%c  ", T->data) ;
     7         PreTraverseTree1(T->leftchild) ;
     8         PreTraverseTree1(T->rightchild) ;
     9     }
    10 }

      2.非递归遍历

       判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。

     1 /*二叉树的非递归先序遍历*/
     2 void PreTraverseTree2(TreeNode * T)
     3 {
     4     StackNode * S ;
     5     TreeNode * p ;
     6     S = NULL ;
     7     p = T ;
     8     S = InitStack(S) ;
     9 
    10     if(NULL == p)
    11     {
    12         printf("树为空!
    ") ;
    13         return ;
    14     }
    15 
    16     while(p || !StackEmpty(S))
    17     {
    18         if(p)
    19         {
    20             StackPush(S, p) ;
    21             printf("%c  ", p->data) ;
    22             p = p->leftchild ;
    23         }
    24         else
    25         {
    26             StackPop(S, p) ;
    27             p = p->rightchild ;
    28         }
    29     }
    30 
    31     free(S) ;
    32 }

    二、中序遍历二叉树

         1.递归遍历

          每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。

     1 /*二叉树递归中序遍历*/
     2 void InOrderTraverseTree1(TreeNode * T)
     3 {
     4     if(T)
     5     {
     6         InOrderTraverseTree1(T->leftchild) ;
     7         printf("%c  ", T->data) ;
     8         InOrderTraverseTree1(T->rightchild) ;
     9     }
    10 }

        2.非递归遍历

        思路基本和先序差不多,只是输出数据的时候不一样。判断栈和树是否为空,若不,则判断树是否为空,不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。

     1 /*二叉树的非递归中序遍历*/
     2 void InOrderTraverseTree2(TreeNode * T)
     3 {
     4     StackNode * S ;
     5     TreeNode * p ;
     6     S = NULL ;
     7     p = T ;
     8     S = InitStack(S) ;
     9 
    10     if(NULL == p)
    11     {
    12         printf("树为空!
    ") ;
    13         return ;
    14     }
    15 
    16     while(p || !StackEmpty(S))
    17     {
    18         if(p)
    19         {
    20             StackPush(S, p) ;
    21             p = p->leftchild ;
    22         }
    23         else
    24         {
    25             StackPop(S, p) ;
    26             printf("%c  ", p->data) ;
    27             p = p->rightchild ;
    28         }
    29     }
    30     free(S) ;
    31 }

    三、后序遍历二叉树

        1.递归遍历

        先判断树是否为空,若不为,先左子树,后右子树,然后根节点。

     1 /*二叉树递归后序遍历*/
     2 void LastTraverseTree1(TreeNode * T)
     3 {
     4     if(T)
     5     {
     6         LastTraverseTree1(T->leftchild) ;
     7         LastTraverseTree1(T->rightchild) ;
     8         printf("%c  ", T->data) ;
     9     }
    10 }

        2.非递归遍历

         要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

     1 /*二叉树非递归后序遍历*/
     2 void LastTraverseTree2(TreeNode * T)
     3 {
     4     StackNode * S ;
     5     TreeNode * cur, * pre ;
     6     S = NULL ;
     7     S = InitStack(S) ;
     8     if(NULL == T)
     9     {
    10         printf("树为空!
    ") ;
    11         return ;
    12     }
    13 
    14     pre = NULL ;    cur = NULL ;
    15     StackPush(S,T) ;
    16     while(!StackEmpty(S))
    17     {
    18         cur = NULL ;
    19         StackGetTop(S,cur) ;
    20         if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild)))
    21         {
    22             printf("%c  ", cur->data) ;
    23             pre = cur ;
    24             StackPop(S,cur) ;
    25         }
    26         else
    27         {
    28             if(cur->rightchild != NULL)
    29             {
    30                 StackPush(S,cur->rightchild) ;
    31             }
    32             if(cur->leftchild != NULL)
    33             {
    34                 StackPush(S,cur->leftchild) ;
    35             }
    36         }
    37     }
    38     free(S) ;
    39 }

    四、层次遍历二叉树

        建立一个队列,先将根节点入队,然后将队首出队,然后判断它的左右子树是否为空,不为空,则先将左子树入队,然后右子树入队。

     1 /*二叉树层次遍历*/
     2 void LevelTraverseTree(TreeNode * T)
     3 {
     4     QueueHead * Q ;
     5     TreeNode * p ;
     6     Q = NULL ;    p = T ;
     7     Q = InitQueue(Q) ;
     8     if(NULL == p)
     9     {
    10         printf("树为空!
    ") ;
    11         return ;
    12     }
    13 
    14     QueuePush(Q,p) ;
    15     while(!QueueEmpty(Q))
    16     {
    17         p = NULL ;
    18         QueuePop(Q,p) ;
    19 
    20         if(NULL != p->leftchild)
    21             QueuePush(Q,p->leftchild) ;
    22 
    23         if(NULL != p->rightchild)
    24             QueuePush(Q,p->rightchild) ;
    25 
    26         printf("%c  ", p->data) ;
    27     }
    28 }

    贴上我自己的全部代码,自己以后可以看,希望或许对别人也有帮助吧,表达能力不行,嘿嘿。

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 typedef struct treenode      //树的节点
      5 {
      6     char data ;
      7     treenode * leftchild, * rightchild ;
      8 }TreeNode;
      9 
     10 typedef TreeNode * StackElemType ;   //定义栈包含的数据类型
     11 
     12 typedef struct stacknode    //栈的节点
     13 {
     14     StackElemType data ;
     15     stacknode * next ;
     16 }StackNode;
     17 
     18 typedef TreeNode * QueueElemType ;     //定义队列包含的数据类型
     19 
     20 typedef struct queuenode     //定义队列节点
     21 {
     22     QueueElemType  data ;
     23     struct queuenode * next ;
     24 }QueueNode;
     25 
     26 typedef struct queuehead    //定义队列的头节点
     27 {
     28     QueueNode * front, * rear ;
     29 }QueueHead;
     30 
     31 //stack的有关声明
     32 StackNode * InitStack(StackNode * S) ;
     33 void StackPush(StackNode * S, StackElemType data) ;
     34 void StackPop(StackNode * S, StackElemType & data) ;
     35 int StackEmpty(StackNode * S) ;
     36 int StackGetTop(StackNode * S, StackElemType & data) ;
     37 
     38 //queue的有关声明
     39 QueueHead * InitQueue(QueueHead * Q) ;
     40 void QueuePush(QueueHead * Q, QueueElemType data) ;
     41 void QueuePop(QueueHead * Q, QueueElemType & data) ;
     42 int QueueEmpty(QueueHead * Q) ;
     43 
     44 //TreeTraverse的有关声明
     45 TreeNode * InitTree(TreeNode * T) ;
     46 void PreTraverseTree1(TreeNode * T) ;
     47 void PreTraverseTree2(TreeNode * T) ;
     48 void InOrderTraverseTree1(TreeNode * T) ;
     49 void InOrderTraverseTree2(TreeNode * T) ;
     50 void LastTraverseTree1(TreeNode * T) ;
     51 void LastTraverseTree2(TreeNode * T) ;
     52 void LevelTraverseTree(TreeNode * T) ;
     53 
     54 //栈的函数定义
     55 StackNode * InitStack(StackNode * S)
     56 {
     57     S = (StackNode *)malloc(sizeof(StackNode)) ;
     58     if(NULL == S)
     59     {
     60         printf("内存不足,不能分配栈!
    ") ;
     61         exit(0) ;
     62     }
     63 
     64     S->next = NULL ;
     65     return(S) ;
     66 }
     67 
     68 void StackPush(StackNode * S, StackElemType data)
     69 {
     70     StackNode * q ;
     71     q = (StackNode *)malloc(sizeof(StackNode)) ;
     72     if(NULL == q)
     73     {
     74         printf("内存不足,不能分配栈!
    ") ;
     75         exit(0) ;
     76     }
     77     q->data = data ;
     78     q->next = S->next ;
     79     S->next = q ;
     80 }
     81 
     82 void StackPop(StackNode * S, StackElemType & data)
     83 {
     84     StackNode * q ;
     85     if(NULL == S->next)
     86     {
     87         printf("栈为空,无返回值!
    ") ;
     88     }
     89 
     90     q = S->next ;
     91     data = q->data ;
     92     S->next = q->next ;
     93     free(q) ;
     94 }
     95 
     96 int StackEmpty(StackNode * S)
     97 {
     98     if(NULL == S->next)
     99     {
    100         return(1) ;
    101     }
    102 
    103     return(0) ;
    104 }
    105 
    106 int StackGetTop(StackNode * S, StackElemType & data)
    107 {
    108     if(NULL != S->next)
    109     {
    110         data = S->next->data ;
    111         return(1) ;
    112     }
    113     else
    114     {
    115         //data = NULL ;
    116         return(0) ;
    117     }
    118 }
    119 
    120 
    121 //队列函数的定义
    122 QueueHead * InitQueue(QueueHead * Q)
    123 {
    124     QueueNode * q ;
    125     Q = (QueueHead *)malloc(sizeof(QueueHead)) ;
    126     if(NULL == Q)
    127     {
    128         printf("内存不足!
    ") ;
    129         exit(0) ;
    130     }
    131     q = (QueueNode *)malloc(sizeof(QueueNode)) ;
    132     if(NULL == q)
    133     {
    134         printf("内存不足!
    ") ;
    135         exit(0) ;
    136     }
    137 
    138     q->next = NULL ;
    139     Q->front = q ;
    140     Q->rear = q ;
    141 
    142     return(Q) ;
    143 }
    144 
    145 void QueuePush(QueueHead * Q, QueueElemType data)
    146 {
    147     QueueNode * q ;
    148     q = (QueueNode *)malloc(sizeof(QueueNode)) ;
    149     if(NULL == q)
    150     {
    151         printf("内存不足!
    ") ;
    152         exit(0) ;
    153     }
    154 
    155     q->data = data ;
    156     q->next = Q->rear->next ;
    157     Q->rear->next = q ;
    158     Q->rear = q ;
    159 }
    160 
    161 void QueuePop(QueueHead * Q, QueueElemType & data)
    162 {
    163     QueueNode * q ;
    164     if(Q->front == Q->rear)
    165     {
    166         printf("队列为空!
    ") ;
    167         return ;
    168     }
    169 
    170     q = Q->front->next ;
    171     data = q->data ;
    172     Q->front->next = q->next ;
    173     if(Q->rear == q)
    174         Q->rear = Q->front ;
    175 
    176     free(q) ;
    177 }
    178 
    179 int QueueEmpty(QueueHead * Q)
    180 {
    181     if(Q->front == Q->rear)
    182         return(1) ;
    183     else
    184         return(0) ;
    185 }
    186 
    187 
    188 //树的各种遍历函数定义
    189 
    190 /*建立一棵二叉树*/
    191 TreeNode * InitTree(TreeNode * T)
    192 {
    193     char data ;
    194     scanf("%c", &data) ;
    195 
    196     if('#' == data)
    197     {
    198         T = NULL ;
    199     }
    200     else
    201     {
    202         T = (TreeNode *)malloc(sizeof(TreeNode)) ;
    203         T->data = data ;
    204         T->leftchild = InitTree(T->leftchild) ;
    205         T->rightchild = InitTree(T->rightchild) ;
    206     }
    207 
    208     return(T) ;
    209 }
    210 
    211 /*二叉树递归先序遍历*/
    212 void PreTraverseTree1(TreeNode * T)
    213 {
    214     if(T)
    215     {
    216         printf("%c  ", T->data) ;
    217         PreTraverseTree1(T->leftchild) ;
    218         PreTraverseTree1(T->rightchild) ;
    219     }
    220 }
    221 
    222 /*二叉树的非递归先序遍历*/
    223 void PreTraverseTree2(TreeNode * T)
    224 {
    225     StackNode * S ;
    226     TreeNode * p ;
    227     S = NULL ;
    228     p = T ;
    229     S = InitStack(S) ;
    230 
    231     if(NULL == p)
    232     {
    233         printf("树为空!
    ") ;
    234         return ;
    235     }
    236 
    237     while(p || !StackEmpty(S))
    238     {
    239         if(p)
    240         {
    241             StackPush(S, p) ;
    242             printf("%c  ", p->data) ;
    243             p = p->leftchild ;
    244         }
    245         else
    246         {
    247             StackPop(S, p) ;
    248             p = p->rightchild ;
    249         }
    250     }
    251 
    252     free(S) ;
    253 }
    254 
    255 /*二叉树递归中序遍历*/
    256 void InOrderTraverseTree1(TreeNode * T)
    257 {
    258     if(T)
    259     {
    260         InOrderTraverseTree1(T->leftchild) ;
    261         printf("%c  ", T->data) ;
    262         InOrderTraverseTree1(T->rightchild) ;
    263     }
    264 }
    265 
    266 /*二叉树的非递归中序遍历*/
    267 void InOrderTraverseTree2(TreeNode * T)
    268 {
    269     StackNode * S ;
    270     TreeNode * p ;
    271     S = NULL ;
    272     p = T ;
    273     S = InitStack(S) ;
    274 
    275     if(NULL == p)
    276     {
    277         printf("树为空!
    ") ;
    278         return ;
    279     }
    280 
    281     while(p || !StackEmpty(S))
    282     {
    283         if(p)
    284         {
    285             StackPush(S, p) ;
    286             p = p->leftchild ;
    287         }
    288         else
    289         {
    290             StackPop(S, p) ;
    291             printf("%c  ", p->data) ;
    292             p = p->rightchild ;
    293         }
    294     }
    295     free(S) ;
    296 }
    297 
    298 /*二叉树递归后序遍历*/
    299 void LastTraverseTree1(TreeNode * T)
    300 {
    301     if(T)
    302     {
    303         LastTraverseTree1(T->leftchild) ;
    304         LastTraverseTree1(T->rightchild) ;
    305         printf("%c  ", T->data) ;
    306     }
    307 }
    308 
    309 /*二叉树非递归后序遍历*/
    310 void LastTraverseTree2(TreeNode * T)
    311 {
    312     StackNode * S ;
    313     TreeNode * cur, * pre ;
    314     S = NULL ;
    315     S = InitStack(S) ;
    316     if(NULL == T)
    317     {
    318         printf("树为空!
    ") ;
    319         return ;
    320     }
    321 
    322     pre = NULL ;    cur = NULL ;
    323     StackPush(S,T) ;
    324     while(!StackEmpty(S))
    325     {
    326         cur = NULL ;
    327         StackGetTop(S,cur) ;
    328         if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild)))
    329         {
    330             printf("%c  ", cur->data) ;
    331             pre = cur ;
    332             StackPop(S,cur) ;
    333         }
    334         else
    335         {
    336             if(cur->rightchild != NULL)
    337             {
    338                 StackPush(S,cur->rightchild) ;
    339             }
    340             if(cur->leftchild != NULL)
    341             {
    342                 StackPush(S,cur->leftchild) ;
    343             }
    344         }
    345     }
    346     free(S) ;
    347 }
    348 
    349 /*二叉树层次遍历*/
    350 void LevelTraverseTree(TreeNode * T)
    351 {
    352     QueueHead * Q ;
    353     TreeNode * p ;
    354     Q = NULL ;    p = T ;
    355     Q = InitQueue(Q) ;
    356     if(NULL == p)
    357     {
    358         printf("树为空!
    ") ;
    359         return ;
    360     }
    361 
    362     QueuePush(Q,p) ;
    363     while(!QueueEmpty(Q))
    364     {
    365         p = NULL ;
    366         QueuePop(Q,p) ;
    367 
    368         if(NULL != p->leftchild)
    369             QueuePush(Q,p->leftchild) ;
    370 
    371         if(NULL != p->rightchild)
    372             QueuePush(Q,p->rightchild) ;
    373 
    374         printf("%c  ", p->data) ;
    375     }
    376 }
    377 
    378 
    379 //主函数的定义
    380 void Tips()
    381 {
    382     printf("建立树是按照先序遍历来建立树的,并且输入‘#’表示子树为空。
    ") ;
    383     printf("请输入要建立的树:") ;
    384 }
    385 
    386 int main()
    387 {
    388     TreeNode * T ;
    389     T = NULL ;
    390 
    391     Tips() ;
    392 
    393     T = InitTree(T) ;
    394 
    395     printf("二叉树递归先序遍历
    ") ;
    396     PreTraverseTree1(T) ;
    397     printf("
    ") ;
    398 
    399     printf("二叉树非递归先序遍历
    ") ;
    400     PreTraverseTree2(T) ;
    401     printf("
    ") ;
    402 
    403     printf("二叉树递归中序遍历
    ") ;
    404     InOrderTraverseTree1(T) ;
    405     printf("
    ") ;
    406 
    407     printf("二叉树非递归中序遍历
    ") ;
    408     InOrderTraverseTree2(T) ;
    409     printf("
    ") ;
    410 
    411     printf("二叉树递归后序遍历
    ") ;
    412     LastTraverseTree1(T) ;
    413     printf("
    ") ;
    414 
    415     printf("二叉树非递归后序遍历
    ") ;
    416     LastTraverseTree2(T) ;
    417     printf("
    ") ;
    418 
    419     printf("二叉树层次遍历
    ") ;
    420     LevelTraverseTree(T) ;
    421     printf("
    ") ;
    422 
    423     return 0 ;
    424 }

    给一个二叉树参考例子:

                                 a

                           b          c

                    d            e

    输入:abd##e##c##

    输出:

    二叉树先序递归遍历:a  b  d  e  c

    二叉树先序非递归遍历:a  b  d  e  c

    二叉树中序递归遍历:d  b  e  a  c

    二叉树中序非递归遍历:d  b  e  a  c

    二叉树后序递归遍历:d  e  b  c  a

    二叉树后序非递归遍历:d  e  b  c  a

    二叉树层次遍历:a  b  c  d  e

  • 相关阅读:
    乐观锁与悲观锁——解决并发问题
    CentOS7 loaded active exited
    ubuntu安装phpVirtualBox web服务
    linux drwxr-xr-x 是什么意思
    phpmyadmin配置文件权限错误,不应任何用户都能修改
    转: CentOS安装jdk8
    PostgreSQL windows service启动失败
    PostgreSQL 添加自定义变量
    数据库检查约束是否存在
    转:PostgreSQL Cheat Sheet
  • 原文地址:https://www.cnblogs.com/fengxmx/p/3764512.html
Copyright © 2020-2023  润新知