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

Posted dishengandziyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树——二叉树的先序中序和后序遍历相关的知识,希望对你有一定的参考价值。

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,遍历结果能够反映树结点访问的先后次序;

以上是关于树——二叉树的先序中序和后序遍历的主要内容,如果未能解决你的问题,请参考以下文章

PTA 二叉树的三种遍历(先序中序和后序)

二叉树的前序中序和后续遍历及应用场景

二叉树遍历的三种方法:先序遍历,中序遍历,后序遍历

创建二叉树非递归完成对二叉树的先序和后序遍历并遍历输出每一层的结点数查找结点P 和结点Q的最近共同祖先

怎么根据二叉树的前序,中序,确定它的后序

二叉树的递归遍历(先序中序和后序)