• 树——二叉树的先序、中序和后序遍历


    1,二叉树是否只有一种遍历方式(层次遍历)?

    2,典型的二叉树的遍历方式:

           1,先序遍历(Pre-Order Traversal);

           2,中序遍历(In-Order Traversal);

           3,后序遍历(Post-Order Traversal);    

    3,先序遍历(“先序”指最先访问根结点中的数据元素):

      1,二叉树为空:

                  1,无操作,直接返回;

           2,二叉树不为空:

                  1,访问根结点中的数据元素;

                  2,先序遍历左子树;

                  3,先序遍历右子树;

      

                 

    4,先序遍历功能定义及其代码实现:

           1,代码示例:

    1    preOrderTraversal(node)
    2        {
    3            if( noe != NULL )
    4            {
    5                access(node->value);
    6                preOrderTraversal(node->left);
    7                preOrderTraversal(node->right);
    8            }
    9        }

      2,功能函数代码实现:

     1    /* 实现先序遍历,队里里面保存的数据元素用来反应遍历时候结点次序 */
     2     void PreOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
     3     {
     4         if( node != NULL )
     5         {
     6             queue.add(node);  // 访问中间结点
     7             PreOrderTraversal(node->left, queue);
     8             PreOrderTraversal(node->right, queue);
     9         }
    10     }

          

    5,中序遍历(“中序”指中间访问根结点中的数据元素):

      1,二叉树为空:

                  1,无操作,直接返回;

           2,二叉树不为空:

                  1,中序遍历左子树;

                  2,访问根结点中的数据元素;

                  3,中序遍历右子树;

     

                 

    6,中序遍历功能定义:

           1,代码示例:

    1    inOrderTraversal(node)
    2        {
    3            if(node != NULL)
    4            {
    5                inOrderTraversal(node->left);
    6                access(node->value);
    7                inOrderTraversal(node->right);
    8            }
    9        }

      2,功能函数代码实现:

     1    /* 实现中序遍历,队里里面保存的数据元素用来反应遍历时候结点次序  */
     2     void inOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
     3     {
     4         if( node != NULL )
     5         {
     6             inOrderTraversal(node->left, queue);
     7             queue.add(node);  // 访问中间结点
     8             inOrderTraversal(node->right, queue);
     9         }
    10     }

    7,后续遍历(“后序”指最后访问根结点中的数据元素):

           1,二叉树为空:

                  1,无操作,直接返回;

           2,二叉树不为空:

                  1,后序遍历左子树;

                  2,后序遍历右子树;

                  3,访问根结点中的数据元素;

                 

    8,后续遍历功能定义:

           1,代码示例:

    1    postOrderTraversal(node)
    2        {
    3            if( node != NULL )
    4            {
    5                postOrderTraversal(node->left);
    6                postOrderTraversal(node->right);
    7                access(node->value);
    8            }
    9        }

      2,功能函数代码实现:

     1    /* 实现后序遍历,队里里面保存的数据元素用来反应遍历时候结点次序  */
     2     void postOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
     3     {
     4         if( node != NULL )
     5         {
     6             postOrderTraversal(node->left, queue);
     7             postOrderTraversal(node->right, queue);
     8             queue.add(node);  // 访问中间结点
     9         }
    10     }

    9,需要考虑的问题:

           1,是否可以将二叉树的典型便利算法集成到 BTree 中?如果可以,代码需要做怎样的改动?

          

    10,设计要点:

           1,不能与层次遍历函数冲突,必须设计新的函数接口;

           2,算法执行完成后,能够方便的获取遍历结果;

           3,遍历结果能够反映结点访问的先后次序;

          

    11,函数接口设计:

           1,SharedPointer<Array<T> > traversal(BTTraversal order):

                  1,根据参数 order 选择执行遍历算法(先序,中序,后序);

                  2,返回值为堆空间中的数组对象(生命周期由智能指针管理);

                  3,数组元素的次序反映遍历的先后次序;

                 

    12,典型遍历示例:

           

    13,遍历算法成员函数实现:

     1,定义遍历方式:
    1 /* 定义排序的方式 */
    2 enum BTTraversal
    3 {
    4     PreOrder,
    5     InOrder,
    6     PostOrder,
    7     LevelOrder  // 重构了“树——二叉树线索化”中的层次遍历次序
    8 };

      2,遍历的功能函数:

     1    /* 遍历的功能函数,第二个参数用于保存访问时,结点的先后顺序 */
     2     void traversal(BTTraversal order, LinkQueue<BTreeNode<T>*>& queue)
     3     {
     4         switch(order)
     5         {
     6             case PreOrder:
     7                 PreOrderTraversal(root(), queue);
     8                 break;
     9             case InOrder:
    10                 inOrderTraversal(root(), queue);
    11                 break;
    12             case PostOrder:
    13                 postOrderTraversal(root(), queue);
    14                 Break;
    15             default:
    16                 THROW_EXCEPTION(InvalidParameterException, "Parameter order is invalid ...");
    17                 break;
    18         }
    19     }

       3,遍历的实现:

     1    /* 典型的二叉树遍历,前序、中序、后续 */
     2     SharedPointer< Array<T> > traversal(BTTraversal order)
     3     {
     4         DynamicArray<T>* ret = NULL;
     5         LinkQueue<BTreeNode<T>*> queue;  // 保存遍历结点次序,用 queue 来传递元素的值是一个很好的抉择;
     6 
     7         traversal(order, queue);  // 执行功能函数
     8 
     9         ret = new DynamicArray<T>(queue.length());  // 申请动态数组
    10 
    11         if( ret != NULL )  // 保存遍历所得的动态数组
    12         {   
    13         /* 将队列中,结点里面数据元素的值,依次放到返回数组里面 */
    14             for(int i=0; i<ret->length(); i++, queue.remove()) // 这里不要忘了将队列依次删除首元素
    15             {
    16                 ret->set(i, queue.front()->value);  // 将结点里面数据元素值依次放到返回数组里面
    17             }
    18         }
    19         else
    20         {
    21             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create return array ...");
    22         }
    23 
    24         return  ret;
    25     }

    14,小结:

           1,二叉树的典型遍历都是以递归方式执行的;

           2,BTree 以不同的函数接口支持典型遍历;

           3,层次遍历与典型遍历互不冲突;

           4,遍历结果能够反映树结点访问的先后次序;

  • 相关阅读:
    Selenium系列(十五)
    Selenium系列(十四)
    Selenium系列(十三)
    Selenium系列(十二)
    Linux常用命令
    Linux
    Linux常用命令
    Linux常用命令
    Mysql常用sql语句(2)- 操作数据表
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/dishengAndziyu/p/10926052.html
Copyright © 2020-2023  润新知