前序:
对上一节内容进行补充和说明:
一般树的链式存储结构:
由于一般树不像二叉树那样结构具有很明显的特点(一个节点至多有两个子节点,若有两个节点后者没有节点的称之为完全二叉树,否则称之为不完全二叉树),所以在一个节点处子节点的个数实质上是不确定的,所以,可以在节点中设置列表L专门用来存储其子节点的引用。如图:
至此,以上关于树的结构问题讨论的已经产不多了,接下来我们一起来探讨,树的遍历算法。
树的遍历算法
什么是遍历?
所谓遍历(Traversal),是指沿着某条搜索路线,依次对树(或图)中每个节点均做一次访问。
树的遍历是一种访问其中所有位置的系统化方法。方位p位置的相关具体行动取决于遍历的应用程序。本节将会为各位介绍树遍历中最常见的几种方式:树的先序遍历、后序遍历、广度优先遍历、二叉树的中序遍历。
1、树的先序遍历和后序遍历
先序遍历:在树T的先序遍历中,首先访问T的根,然后再递归访问子树的根。如果这棵树是有序的,则根据子节点的顺序遍历子树。对于位置p处子树的根的先序遍历,其为代码如下:
方法 preorder(T, p):
对位置p先进行访问操作,然后做以下内容
for 每个子节点c in T.children(p):
preorder(T, c)
遍历过程如图:
后序遍历:可以看做是先序遍历的相反过程,从位置p的子节点开始遍历,最后回到p的根。如图:
伪代码:
方法 preorder(T, p):
for 每个子节点c in T.children(p):
preorder(T, c)
对位置p先进行访问操作,然后做以下内容
2、树的广度优先遍历:
另外一种常见的方法是广度优先遍历,访问深度d的位置之前先访问深度d+1的位置。
广度优先最常见的引用是在游戏中。
广度优先遍历的伪代码,这个过程不是递归的,因为我们不是首先遍历整个字数。我们使用一个队列来产生FIFO访问节点顺序的语义。如下:
breadfirstMethod(T):
初始化序列Q,找到树根
while Q 非空:
p = Q.dequeue()
对位置p先进行访问操作,然后做以下内容
for 每个子节点c in T.children(p):
Q.enqueue(c)
3、二叉树的中序遍历:
这是一种专门应用于二叉树的遍历算法。在中序遍历中,我们通过递归遍历左右子树去访问一个位置。二叉树的中序遍历可以看做 ‘从左到右’非正式地访问T的节点,实际上,对于每个位置p,p都会在其左子节点之后,右子节点之前被中序遍历所访问。中序遍历的伪代码如下:
inorder(p):
if p 有左子节点c:
调用inorder(c)
对位置p进行的操作
if p有右子节点d:
调用inorder(d)
中序遍历可能最常用的地方就是将有序序列的元素存储在二叉树当中,这种结构称之为二叉搜索树。S可能是一个数组,S的二叉搜索树是T,对于T的每一个位置p,都有:
1、位置p存储S的一个元素,记为e( p )
2、存储在p的左子树的元素(如果有的话)小于e( p )
3、存储在p的右子树的元素(如果有的话)大于e( p )
我们可以为数组S 使用二叉搜索树T,来寻找S中的元素v,从根开始遍历树T下的路径,在p遇到的每个内部位置,我们比较搜索值v和存储在p位置的e( p ),如果v小于e( p ),则继续搜索p的左子树;如果v大于e( p ),则继续搜索p的右子树; 如果v== e( p ), 则证明找到元素v ;但是如果搜索最终到达一个空的子树,则搜索失败。
中序遍历的执行逻辑:
例如就是如上的序列使用二叉搜索树去寻找12这个值,则可图示为:
佛系养生编程,请关注小白piao,带你轻松学python。