• 二叉树前中后序递归和非递归的实现


    以防生疏,所以今天又写了一下二叉树的前中后序递归和非递归的实现:

    二叉树的节点数据结构:

    1 struct BinaryTreeNode
    2 {
    3     int nData;
    4 
    5     BinaryTreeNode *lChild;
    6     BinaryTreeNode *rChild;
    7 };

    最后用来测试的树:

                      1

                   /     \

                2          4

                    \      /    \

                      3 5       6

                                     \

                                       7

    前序递归代码:

     1 void RecursionBinaryTreePreOrder(BinaryTreeNode *root)
     2 {
     3     if (NULL == root)
     4     {
     5         return;
     6     }
     7 
     8     // 打印根节点
     9     cout << root->nData << " ";
    10 
    11     // 打印左孩子
    12     RecursionBinaryTreePreOrder (root->lChild);
    13 
    14     // 打印右孩子
    15     RecursionBinaryTreePreOrder (root->rChild);
    16 }

    二叉树前序非递归遍历写了两种方式:

     1 // 两种二叉树前序的非递归遍历方式
     2 // 第一种
     3 void BinaryTreePreOrder(BinaryTreeNode *root)
     4 {
     5     assert (root != NULL);
     6 
     7     BinaryTreeNode *Stack[MAX];
     8     int nTop = -1;
     9 
    10     // 根节点入栈
    11     Stack[++nTop] = root;
    12     
    13     while (nTop >= 0)
    14     {
    15         // 弹出并访问根节点
    16         BinaryTreeNode *pTemp = Stack[nTop--];
    17 
    18         cout << pTemp->nData << " ";
    19 
    20         // 因为根节点的左孩子要优于右孩子先访问,
    21         // 根据栈FILO(先进后出)的特点,因此根节点的右孩子要先入栈
    22         if (pTemp->rChild != NULL)
    23         {
    24             Stack[++nTop] = pTemp->rChild;
    25         }
    26 
    27         if (pTemp->lChild != NULL)
    28         {
    29             Stack[++nTop] = pTemp->lChild;
    30         }
    31     }
    32 }
     1 // 另一种非递归方式,这种方式是用栈来严格模拟递归的遍历方式
     2 void AnotherBinaryTreePreOrder(BinaryTreeNode *root)
     3 {
     4     assert (root != NULL);
     5 
     6     BinaryTreeNode *Stack[MAX];
     7     int nTop = -1;
     8     BinaryTreeNode *pTemp = root;
     9 
    10     while (pTemp != NULL)
    11     {
    12         cout << pTemp->nData << " ";
    13 
    14         Stack[++nTop] = pTemp;
    15         pTemp = pTemp->lChild;
    16     }
    17 
    18     while (nTop >= 0)
    19     {
    20         pTemp = Stack[nTop--]->rChild;
    21 
    22         while (pTemp != NULL)
    23         {
    24             cout << pTemp->nData << " ";
    25 
    26             Stack[++nTop] = pTemp;
    27             pTemp = pTemp->lChild;
    28         }
    29     }
    30 }

    中序递归遍历:

     1 // 二叉树中序的递归遍历方式
     2 void RecursionBinaryTreeInOrder(BinaryTreeNode *root)
     3 {
     4     if (NULL == root)
     5     {
     6         return;
     7     }
     8 
     9     // 先打印左孩子
    10     RecursionBinaryTreeInOrder (root->lChild);
    11 
    12     // 再打印根节点
    13     cout << root->nData << " ";
    14 
    15     // 最后打印右孩子
    16     RecursionBinaryTreeInOrder (root->rChild);
    17 }

    中序非递归遍历:

     1 // 二叉树中序的非递归遍历方式,用栈严格模拟递归的调用
     2 void BinaryTreeInOrder(BinaryTreeNode *root)
     3 {
     4     assert (root != NULL);
     5 
     6     BinaryTreeNode *Stack[MAX];
     7     int nTop = -1;
     8 
     9     // 根节点首先入栈
    10     Stack[++nTop] = root;
    11 
    12     // 先要打印左孩子
    13     BinaryTreeNode *Current = root->lChild;
    14 
    15     while ((Current != NULL) || (nTop >= 0))
    16     {
    17         while (Current != NULL)
    18         {
    19             Stack[++nTop] = Current;
    20             Current = Current->lChild;
    21         }
    22 
    23         // 打印根节点
    24         Current = Stack[nTop--];
    25         cout << Current->nData << " ";
    26 
    27         // 打印右孩子
    28         Current = Current->rChild;
    29     }
    30 }

    后序递归遍历:

     1 // 二叉树后序的递归遍历方式
     2 void RecursionBinaryTreePostOrder(BinaryTreeNode *root)
     3 {
     4     if (NULL == root)
     5     {
     6         return;
     7     }
     8 
     9     // 打印左孩子
    10     RecursionBinaryTreePostOrder (root->lChild);
    11 
    12     // 打印右孩子
    13     RecursionBinaryTreePostOrder (root->rChild);
    14 
    15     // 打印根节点
    16     cout << root->nData << " ";
    17 }

    后序非递归遍历也写了两种方式:

     1 // 二叉树后序的一种非递归遍历方式
     2 void BinaryTreePostOrder(BinaryTreeNode *root)
     3 {
     4     assert (root != NULL);
     5 
     6     BinaryTreeNode *Stack[MAX];
     7     int nTop = -1;
     8 
     9     BinaryTreeNode *Current = root;
    10     BinaryTreeNode *Previewed = NULL;
    11 
    12     while ((Current != NULL) || (nTop >= 0))
    13     {
    14         // 打印左孩子
    15         while (Current != NULL)
    16         {
    17             Stack[++nTop] = Current;
    18             Current = Current->lChild;
    19         }
    20 
    21         // 左孩子打印完,当其没有右孩子或右孩子已经被访问过,就打印根节点
    22         // ,否则打印右孩子
    23         Current = Stack[nTop];
    24 
    25         if ((NULL == Current->rChild) || (Previewed == Current->rChild))
    26         {
    27             cout << Current->nData << " ";
    28             Previewed = Current;
    29             Current = NULL;
    30             --nTop;
    31         }
    32         else
    33         {
    34             Current = Current->rChild;
    35         }
    36     }
    37 }
     1 // 二叉树后序的另一种非递归遍历方式
     2 void AnotherBinaryTreePostOrder(BinaryTreeNode *root)
     3 {
     4     assert (root != NULL);
     5 
     6     BinaryTreeNode *Stack1[MAX];
     7     int nTop1 = -1;
     8 
     9     BinaryTreeNode *Stack2[MAX];
    10     int nTop2 = -1;
    11 
    12     Stack1[++nTop1] = root;
    13 
    14     while (nTop1 >= 0)
    15     {
    16         BinaryTreeNode *pTemp = Stack1[nTop1--];
    17         Stack2[++nTop2] = pTemp;
    18 
    19         if (pTemp->lChild != NULL)
    20         {
    21             Stack1[++nTop1] = pTemp->lChild;
    22         }
    23 
    24         if (pTemp->rChild != NULL)
    25         {
    26             Stack1[++nTop1] = pTemp->rChild;
    27         }
    28     }
    29 
    30     while (nTop2 >= 0)
    31     {
    32         cout << Stack2[nTop2--]->nData << " ";
    33     }
    34 }

    测试结果:

  • 相关阅读:
    城市承灾体脆弱性和易损性的影响因素
    《风暴潮、海浪、海啸和海冰灾害应急预案》
    承灾体
    ArcGIS数据存储的方式
    ArcGIS几种数据格式2
    ArcGIS几种数据格式
    【ArcGIS】文件地理数据库,个人地理数据库与ArcSDE的局别
    dojo事件绑定
    Spark最简安装
    Spark 概述
  • 原文地址:https://www.cnblogs.com/ldjhust/p/3054322.html
Copyright © 2020-2023  润新知