二叉树遍历指沿着魔调搜索路径访问二叉树的结点,每个结点被访问的次数有且仅有一次。
先序遍历
先遍历根节点,再遍历左子树,最后遍历右子树,如图1。
递归算法
递归算法结构简单,易于实现,但是在时间上开销较大,运行效率较低。
/**
* @param BiTreeNode root 根结点
*/
public void preOrder(BiTreeNode root) {
if (root == null) {
return;
}
System.out.print(root.data + "...");
preOrder(root.lchild);
preOrder(root.rchild);
}
非递归算法
解决了递归算法中运行效率低下的问题
可以使用临时遍历保存中间结果,用循环结构代替递归过程;或者利用栈保存中间结果。
核心思想
从二叉树的根结点出发,沿着该结点的左子树向下搜索,每遇到一个结点先访问该结点,并将其右子树入栈。在左子树遍历完成后,将右子树出栈,在重复上述过程,直到栈为空。步骤如下:
- 将二叉树的根结点入栈
- 若栈非空,将结点从栈中弹出并访问
- 依次访问当前访问结点的左孩子结点,并将当前结点的右孩子结点入栈
- 重复步骤2和3,知道栈为空
代码实现
import ch03.LinkStack;
/**
* @param BiTreeNode root 根结点
*/
public void preOrder2(BiTreeNode root) {
BiTreeNode p = root;
if (p != null) {
LinkStack s = new LinkStack();
try {
s.push(p);
} catch (Exception e) {
e.getMessage();
}
while (!s.isEmpty()) {
p = (BiTreeNode) s.pop();
System.out.print(p.data + "...");
while (p != null) {
if (p.lchild != null) {
System.out.print(p.lchild.data + "...");
}
if (p.rchild != null) {
try {
s.push(p.rchild);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}