代码改变世界

数据结构与算法回顾之二叉树的遍历(上)

2010-12-12 21:57  yearN  阅读(474)  评论(0编辑  收藏  举报

所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。
遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。

常用的遍历方法有深度优先遍历和广度优先遍历,广度优先遍历就是二叉树的层序遍历,按照自顶向下、自左向右的方式访问二叉树节点。而深度优先遍历可以按某种次序执行三个操作:
     (1)访问结点本身(N),
     (2)遍历该结点的左子树(L),
     (3)遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
     NLR、LNR、LRN、NRL、RNL、RLN。

 前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。这三种遍历

根据访问结点操作发生位置命名:
  ① NLR:前序遍历(PreorderTraversal亦称(先序遍历))
         ——访问结点的操作发生在遍历其左右子树之前。
  ② LNR:中序遍历(InorderTraversal)
        ——访问结点的操作发生在遍历其左右子树之中(间)。
   ③ LRN:后序遍历(PostorderTraversal)
        ——访问结点的操作发生在遍历其左右子树之后。

对于深度优先和广度优先这两种遍历算法,它的c#实现代码如下:

 

using System;
using System2.Collections.Generic;//自定义的栈和队列,详细见<数据结构与算法回顾之栈和队列>

namespace Alg
{
    /// <summary>
    /// 二叉树的遍历算法
    /// </summary>
    public class Traversal
    {
        /// <summary>
        /// 自顶向下自左向右的广度优先遍历
        /// </summary>
        /// <param name="root">根节点</param>
        public void BreadFirst(BSTNode root)
        {
            BSTNode p = root;
            Queue<BSTNode> queue = new Queue<BSTNode>();
            if (p != null)
            {
                queue.Enqueue(p);
                while (!queue.IsEmpty())
                {
                    p = queue.Dequeue();
                    BST.Visit(p);
                    if (p.Left != null)
                    {
                        queue.Enqueue(p.Left);
                    }
                    if (p.Right != null)
                    {
                        queue.Enqueue(p.Right);
                    }
                }
            }
        }

        //以下为深度优先遍历...

        /// <summary>
        /// 深度优先遍历-先序遍历(递归实现)
        /// </summary>
        /// <param name="p">开始节点</param>
        public void Preorder(BSTNode p)
        {
            if (p != null)
            {
                BST.Visit(p);
                Preorder(p.Left);
                Preorder(p.Right);
            }
        }

        /// <summary>
        /// 深度优先遍历-中序遍历(递归实现)
        /// </summary>
        /// <param name="p">开始节点</param>
        public void Inorder(BSTNode p)
        {
            if (p != null)
            {
                Preorder(p.Left);
                BST.Visit(p);
                Preorder(p.Right);
            }
        }

        /// <summary>
        /// 深度优先遍历-后序遍历(递归实现)
        /// </summary>
        /// <param name="p">开始节点</param>
        public void Postorder(BSTNode p)
        {
            if (p != null)
            {
                Preorder(p.Left);
                Preorder(p.Right);
                BST.Visit(p);
            }
        }
    }
}