Fork me on GitHub

数据结构——二叉树遍历之“递归与非递归遍历”

简述

二叉树的遍历分为先序遍历、中序遍历和后序遍历。如下图所示:

 

递归遍历

private void bianli1(List<Integer> list, TreeNode root) {
    // 先序遍历
    if (root == null) {
        return;
    }
    list.add(root.val);
    bianli1(list, root.left);
    bianli1(list, root.right);
}

private void bianli2(List<Integer> list, TreeNode root) {
    // 中序遍历
    if (root == null) {
        return;
    }
    bianli2(list, root.left);
    list.add(root.val);
    bianli2(list, root.right);
}

private void bianli3(List<Integer> list, TreeNode root) {
    // 后序遍历
    if (root == null) {
        return;
    }
    bianli3(list, root.left);
    bianli3(list, root.right);
    list.add(root.val);
}

递归遍历实现比较简单,递归利用函数栈来保存信息。

非递归遍历

非递归需要额外自己申请数据结构来代替函数栈。

先序遍历:

1.申请一个栈 stack。然后将头结点 head 压入 stack 中。
2.从 stack 中弹出栈顶结点,记为 cur,然后打印 cur 结点的值,再将 cur 的右孩子(非空的话)和左孩子(非空的话)分别压入栈中。
3.不断重复步骤 2,直到栈 stack 为空,全部过程结束。

中序遍历:

1.申请一个栈 stack。初始时,令变量 cur=head。
2.先把 cur 结点压入栈中,然后依次把左边界压入栈中,即不停的令 cur=cur.left,重复该步骤。
3.不断重复步骤 2,直到 cur 为空为止,此时从 stack 中弹出栈顶元素,记为 node。打印 node 的值,并将 cur=node.right,然后继续重复步骤2。
4.当 stack 为空且 cur 为空时,整个过程停止。

后序遍历:

1.申请一个栈,记为s1,然后将头结点 head 压入 s1 中。
2.从 s1 中弹出的结点记为 cur,然后依次将 cur 的左孩子和右孩子压入 s1 中。
3.整个过程中 s1 所弹出的结点都压入 s2 中。
4.不断重复步骤2-3,直到 s1 为空为止。
5.从 s2 中弹出结点并打印,打印的顺序就是后序遍历的顺序。

源码实现:

/**
 * 先序遍历
 */
private static void xianxu(List<Integer> list, TreeNode root) {
    Stack<TreeNode> stack = new Stack<TreeNode>();
    stack.add(root);
    while (!stack.isEmpty()) {
        root = stack.pop();
        list.add(root.val);
        if (root.right != null) {
            stack.push(root.right);
        }
        if (root.left != null){
            stack.push(root.left);
        }

    }
}
/**
 * 中序遍历
 */
private static void zhongxu(List<Integer> list, TreeNode root) {
    Stack<TreeNode> stack = new Stack<TreeNode>();
    while (!stack.isEmpty() || root!=null) {
        if (root != null) {
            stack.push(root);
            root = root.left;
        }else {
            root = stack.pop();
            list.add(root.val);
            root = root.right;
        }
    }
}
/**
 * 后序遍历
 */
private static void houxu(List<Integer> list, TreeNode root) {
    Stack<TreeNode> stack1 = new Stack<TreeNode>();
    Stack<TreeNode> stack2 = new Stack<TreeNode>();
    stack1.add(root);
    while (!stack1.isEmpty()) {
        root = stack1.pop();
        stack2.push(root);
        if (root.left != null) {
            stack1.push(root.left);
        }
        if (root.right != null) {
            stack1.push(root.right);
        }
    }
    while (!stack2.isEmpty()) {
        list.add(stack2.pop().val);
    }
}

参考资料

[1] 程序员代码面试, 第三章 - 二叉树问题

posted @ 2017-03-17 22:52  郑斌blog  阅读(1628)  评论(0编辑  收藏  举报