首页 > 代码库 > 数据结构——二叉树遍历之“递归与非递归遍历”

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

简述

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

技术分享

 

递归遍历

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] 程序员代码面试, 第三章 - 二叉树问题

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