层序遍历
二叉树的遍历的核心问题就是:二维结构的线性化。
简单来说就是以下两个操作:
- 从结点访问其左、右儿子结点
- 访问左儿子后,右儿子结点怎么办?
因为树是二维结构,即一个结点是连接了两个结点。当我访问了某个结点的其中一个子结点后,另外一个要怎么办?肯定要把它保存起来,或者把自己保存起来,因为我自己在,我就可以找到另外一个子结点。因此我们需要考虑如何解决上述的问题。方法如下:
-
需要一个存储结构保存暂时不访问的结点
-
存储结构:堆栈、队列
什么是层序遍历
层序遍历是比较接近人的思维方式的一种遍历方法,将二叉树的每一层分别遍历,直到最后的叶子节点被全部遍历完,这里要用到的辅助数据结构是队列,队列具有先进先出的性质。
为什么用队列?
从二叉树的第一层(根节点)开始,从上至下逐层遍历,在每一层中又按照从左到右的顺序对结点逐个遍历。我们可以看出如果某个结点比同一层的先遍历,其孩子也将比其同层的孩子结点先遍历,这种先进先出的方式,是队列的性质。
层序遍历的实现过程:
层序基本过程:先根结点入队,然后:
①从队列中取出一个元素;
②访问该元素所指结点;
③若该元素所指结点的左、右孩子结点非空,
则将其左、右孩子的指针顺序入队。
代码如下:
void LevelOrderTraversal ( BinTree BT )
{
Queue Q; BinTree T;
if ( !BT ) return; /* 若是空树则直接返回 */
Q = CreatQueue( MaxSize ); /*否则创建并初始化队列Q*/
AddQ( Q, BT );
while ( !IsEmptyQ( Q ) )
{
T = DeleteQ( Q );
printf(“%d\n”, T->Data); /*访问取出队列的结点*/
if ( T->Left ) AddQ( Q, T->Left );/*左孩子存在就将左孩子压入队列*/
if ( T->Right ) AddQ( Q, T->Right );/*右孩子存在就将右孩子压入队列*/
}
}