【上下左右】代表从上到下同时从左往右的遍历顺序,上下左右和下上右左其实是同一个问题。
1.上下左右遍历
上下左右遍历要借用到一个队列。
树根A第一个入栈,然后根结点的左右孩子BC紧随其后。front移动到A时把A访问并出队,接着front向队列后继续移动,在front不断后移的过程中,每移动到一个新的结点(队列中的一个空)就把这个结点的孩子lchild和rchild(如果有)再加入到队列中(先加左再加右)。这种入队循序保证了队列中高层的结点总在低层的前边,同一层中左边结点的总在右边的前面。
Void LevelOrder(BiTree T){
InitQueue(Q);//创建队列
BiTree p;//p当作光标
EnQueue(Q,T);//首先把树的根结点入队,此步骤不在循环中
while(!IsEmpty(Q)){//队列非空时循环
DeQueue(Q,p);//把队头出队,同时把p标记到出队的那个结点上准备访问和入队其孩子
visit(p);//↑此处直接用DeQueue()函数来出队是简略的写,实际其中包含front后移等操作
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
}
2.下上右左遍历
实际上下上右左遍历的结果和上下左右遍历刚好是一个头尾相反的过程,在上下左右中我们每次循环用一次EnQueue()出队一个结点(以访问)并推进到队列中下一个结点,最终效果是把队列中元素按从头到尾输出了。既然下上右左是刚好相反的过程,那只用加一个栈,每次循环出队时把那个出队的结点再入栈,全部完成后正常输出栈,就变成了按队列从尾到头的顺序。
Void LevelOrder2(BiTree T){
InitQueue(Q);
InitStack(S);
BiTree p;
EnQueue(T);
while(!IsEmpty(Q)){
DeQueue(Q,p);
Push(S,p);//把刚出队的p入栈
visit(p);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild)
EnQueue(Q,p->rchild);
}
//然后出栈S,此处不考虑
}