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

时间:2022-12-17 17:53:04

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