zoukankan      html  css  js  c++  java
  • 数据结构——二叉树遍历之“递归与非递归遍历”

    简述

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

    递归遍历

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

  • 相关阅读:
    吴裕雄--天生自然Android开发学习:android 背景相关与系统架构分析
    吴裕雄--天生自然Android开发学习:魅蓝3开启USB调试
    吴裕雄--天生自然Android开发学习:下载安装android stuio集成开发工具
    吴裕雄--天生自然python学习笔记:Python uWSGI 安装配置
    吴裕雄--天生自然python学习笔记:Python MongoDB
    zoj 2022
    ZOJ2006 一道很尴尬的string操作题
    ZOJ 2002 Copying Books 二分 贪心
    ZOJ-3933-Team Formation【二分图最佳匹配】【KM】
    ZOJ1181 Word Amalgamation 字符串 排序查找
  • 原文地址:https://www.cnblogs.com/zhengbin/p/6569068.html
Copyright © 2011-2022 走看看