遍历的概念

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次。树的3种最重要的遍历方式分别称为前序遍历、中序遍历和后序遍历。以这3种方式遍历一棵树时,若按访问结点的先后次序将结点排列起来,就可分别得到树中所有结点的前序列表,中序列表和后序列表。相应的结点次序分别称为结点的前序、中序和后序。

树遍历的方法

树的这3种遍历方式可递归地定义如下:

如果T是一棵空树,那么对T进行前序遍历、中序遍历和后序遍历都是空操作,得到的列表为空表。

如果T是一棵单结点树,那么对T进行前序遍历、中序遍历和后序遍历都只访问这个结点。这个结点本身就是要得到的相应列表。

否则,设T如图6所示,它以n为树根,树根的子树从左到右依次为T1,T2,..,Tk,那么有:

对T进行前序遍历是先访问树根n,然后依次前序遍历T1,T2,..,Tk。

对T进行中序遍历是先中序遍历T1,然后访问树根n,接着依次对

T2,T2,..,Tk进行中序遍历。

对T进行后序遍历是先依次对T1,T2,..,Tk进行后序遍历,最后访问树根n。

n

/ | \

/ | \

/ | \

/ ... | ... \

T1 T2 T3

程序代码

前序遍历和中序遍历可形式地依次描述如下:

三种遍历可以形式地描述如下,其中用到了树的ADT操作:

Procedure Preorder_Traversal(v:NodeType); {前序遍历算法} begin

Visite(v); {访问节点v}

i:=Leftmost_Child(v);

while i<>∧ do

Preorder_Traversal(i);{从左到右依次访问v的每一个儿子节点i} i:=Right_Sibling(i);

end;

end;

Procedure Inorder_Traversal(v:NodeType); {中序遍历算法}

begin

if Leftmost_Child(v)=∧ {判断v是否是叶节点}

then Visite(v)

else

begin

Inorder_Traversal(Leftmost_Child(v)); {中序遍历v的左边第一个

儿子节点}

Visite(v); {访问节点v}

i:=Right_Sibling(Leftmost_Child(v)); {i=v的左边第二个儿子} while i<>∧ do

begin

Inorder_Traversal(i);

{从左边第二个开始到最右边一个为止依次访问v的每一个儿子节点i} i:=Right_Sibling(i);

end;

end;

end;

Procedure Postorder_Traversal(v:NodeType); {后序遍历算法}

begin

i:=Leftmost_Child(v);

while i<>∧ do

begin

Preorder_Traversal(i);{从左到右依次访问v的每一个儿子节点i} i:=Right_Sibling(i);

end;

Visite(v); {访问节点v}

end;

为了将一棵树中所有结点按某种次序列表,只须对树根调用相应过程。例如对图7中的树进行前序遍历、中序遍历和后序遍历将分别得到前序列表:A B E F I J C D G H;中序列表:E B I F J A C G D H;后序列表:E I J F B C G H D A。

下面介绍一种方法可以产生上述3种遍历方式的结点列表。设想我们从树根出发,依逆时针方向沿树的外缘绕行(例如围绕图7中的树绕行的路线如图8所示)。绕行途中可能多次经过同一结点。如果我们按第一次经过的时间次序将各个结点列表,就可以得到前序列表;如果按最后一次经过的时间次序列表,也就是在即将离开某一结点走向其父亲时将该结点列出,就得到后序列表。为了产生中序列表,要将叶结点与内部结点加以区别。叶结点在第一次经过时列出,而内部结点在第二次经过时列出。

在上述3种不同次序的列表方式中,各树叶之间的相对次序是相同的,它们都按树叶之间从左到右的次序排列。3种列表方式的差别仅在于内部结点之间以及内部结点与树叶之间的次序有所不同。

一棵树进行前序列表或后序列表有助于查询结点间的祖先子孙关系。假设结点v在后序列表中的序号(整数)为postorder(v),我们称这个整数为结点v的后序编号。例如在图7中,结点E,I和J的后序编号分别为1,2和3。

编号性质

结点的后序编号具有这样的特点:设结点v的真子孙个数为desc(v),那么在以v为根的子树中的所有结点的后序编号恰好落在postorder(v)- desc(v)与postorder(v)之间。因此为了检验结点x是否为结点y的子孙,我们只要判断它们的后序编号是否满足:

postorder(y)-desc(y)≤postorder(x)≤postorder(y)

前序编号也具有类似的性质。

编辑本段二叉树遍历

遍历方案

从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。

因此,在任一给定结点上,可以按某种次序执行三个操作:

(1)访问结点本身(N),

(2)遍历该结点的左子树(L),

(3)遍历该结点的右子树(R)。

以上三种操作有六种执行次序:

NLR、LNR、LRN、NRL、RNL、RLN。

注意:

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

相关文档
最新文档