前言
二叉树的非递归遍历对于初学者来说可能不太容易掌握,其实它源于递归遍历,只是把递归栈换成了我们自己的栈。掌握了这一点,无论是先序中序还是后序都非常简单。
思路
按照先序“根左右”的原则,沿着左子树向下,先访问根节点,并将其压入栈中(目的是便于后面遍历右子树有结点可依)直到结点为空(到达了最左端),由于此时需要访问右子树,因而需要退栈,访问退栈结点的右孩子。而后继续循环(又沿左子树向下遍历)直到栈空为止。
代码
/**
* 定义二叉树结构
* @author Fairy2016
*
*/
class BiTree {
int data;
BiTree lchild;
BiTree rchild;
}
/**
* 定义栈结构
* @author Fairy2016
*
*/
class Stack {
BiTree nodes[];
int top;
}
/**
* 遍历
* @author Fairy2016
*
*/
public class BiTreeThrough {
//根据给定序列,建立完全二叉树
public static BiTree CreateCompleteBiTree(int a[], int n) {
BiTree nodes[] = new BiTree[n];
//初始化各结点
for(int i = 0; i < n; i++) {
nodes[i] = new BiTree();
nodes[i].data = a[i];
nodes[i].lchild = nodes[i].rchild = null;
}
//将各结点按照完全二叉树的关系连起来(其实就是奇左偶右)
for(int i = 1; i <= n/2; i++) {
nodes[i-1].lchild = nodes[2*i-1];
if(2*i < n) {
nodes[i-1].rchild = nodes[2*i];
}
}
//返回根结点
return nodes[0];
}
//递归遍历
public static void ReCuPreOrder(BiTree T) {
if(T != null) {
System.out.print(T.data+" ");
ReCuPreOrder(T.lchild);
ReCuPreOrder(T.rchild);
}
}
//非递归遍历
public static void NotReCuPreOrder(BiTree T) {
//栈初始化
Stack S = new Stack();
S.top = -1;
S.nodes = new BiTree[100];
BiTree p = T;
//遍历
while(p != null || S.top != -1) {
if(p != null) {
System.out.print(p.data+" ");//访问
S.nodes[++S.top] = p;//入栈
p = p.lchild;//沿左子树向下
} else {
p = S.nodes[S.top--];//出栈
p = p.rchild;//沿右子树
}
}
}
//执行
public static void main(String args[]) {
int a[] = {1,2,3,4,5,6,7,8};
int n = 8;
BiTree T = CreateCompleteBiTree(a, n);
NotReCuPreOrder(T);
}
}