• 二叉树的遍历


    二叉树的遍历分为两大类:

    1、深度优先遍历(前序遍历、中序遍历、后序遍历)

    2、广度优先遍历

             3

        2             8

    9    10     null        4

    package xiaohui;
    
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.Stack;
    
    /**
     * @author 忠哥
     * @create 2021-10-24
     **/
    public class CreateBinaryTreeByLinkedList {
        /**
         * 构建二叉树
         *
         * @param linkedList 链表
         * @return
         */
        public static TreeNode createTreeNode(LinkedList<Integer> linkedList) {
            TreeNode node = null;
            if (linkedList == null || linkedList.isEmpty()) {
                return null;
            }
            //从链表中移除第一个并将其返回
            Integer data = linkedList.removeFirst();
            //如果元素为空,则不再递归
            if (data != null) {
                node = new TreeNode(data);
                node.left = createTreeNode(linkedList);
                node.right = createTreeNode(linkedList);
            }
            return node;
        }
    
        /**
         * 前序遍历
         *
         * @param node
         */
        public static void preOut(TreeNode node) {
            if (node == null) {
                return;
            }
            System.out.print(node.data + "	");
            preOut(node.left);
            preOut(node.right);
        }
    
        /**
         * 借助栈实现 前序遍历
         *
         * @param root
         */
        public static void preOutStack(TreeNode root) {
            TreeNode treeNode = root;
            Stack<TreeNode> stack = new Stack<>();
            while (treeNode != null || !stack.isEmpty()) {
                while (treeNode != null) {
                    System.out.print(treeNode.data + "	");
                    stack.push(treeNode);
                    treeNode = treeNode.left;
                }
                if (!stack.isEmpty()) {
                    treeNode = stack.pop();
                    treeNode = treeNode.right;
                }
            }
        }
    
        /**
         * 用非递归的方式实现二叉树的先序遍历(LeetCode144):
         * 1、申请一个栈stack,然后将头节点压入stack中。
         * 2、从stack中弹出栈顶节点,打印,再将其右孩子节点(不为空的话)先压入stack中,最后将其左孩子节点(不为空的话)压入stack中。
         * 3、不断重复步骤2,直到stack为空,全部过程结束。
         *
         * @param root
         */
        private static void doPreOutStack(TreeNode root) {
            Stack<TreeNode> stack = new Stack<>();
            if (root != null) {
                stack.push(root);
                while (!stack.empty()) {
                    TreeNode node = stack.pop();
                    System.out.print(node.data + "	");
                    if (node.right != null) {
                        stack.push(node.right);
                    }
                    if (node.left != null) {
                        stack.push(node.left);
                    }
                }
            }
        }
    
        /**
         * 中序遍历
         *
         * @param node
         */
        public static void midOut(TreeNode node) {
            if (node == null) {
                return;
            }
            midOut(node.left);
            System.out.print(node.data + "	");
            midOut(node.right);
        }
    
        /**
         * 用非递归的方式实现二叉树的中序遍历(LeetCode94):
         * 1、申请一个栈stack,初始时令cur=head
         * 2、先把cur压入栈中,依次把左边界压入栈中,即不停的令cur=cur.left,重复步骤2
         * 3、不断重复2,直到为null,从stack中弹出一个节点,记为node,打印node的值,并令cur=node.right,重复步骤2
         * 4、当stack为空且cur为空时,整个过程停止。
         *
         * @param root
         */
        private static void doMidOutStack(TreeNode root) {
            Stack<TreeNode> stack = new Stack<>();
            if (root != null) {
                while (root != null || !stack.isEmpty()) {
                    if (root != null) {
                        stack.push(root);
                        root = root.left;
                    } else {
                        root = stack.pop();
                        System.out.print(root.data + "	");
                        root = root.right;
                    }
    
                }
            }
        }
    
        /**
         * 后序遍历
         *
         * @param node
         */
        public static void lastOut(TreeNode node) {
            if (node == null) {
                return;
            }
            lastOut(node.left);
            lastOut(node.right);
            System.out.print(node.data + "	");
        }
    
        /**
         * 用非递归的方式实现二叉树的后序遍历(LeetCode145):
         * 用非递归的方式实现后序遍历有点麻烦。
         * 1、申请一个栈s1,然后将头节点压入栈s1中。
         * 2、从s1中弹出的节点记为cur,然后依次将cur的左孩子节点和右孩子节点压入s1中。
         * 3、在整个过程中,每一个从s1中弹出的节点都放进s2中。
         * 4、不断重复步骤2和步骤3,直到s1为空,过程停止。
         * 5、从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序。
         *
         * @param root
         */
        private static void doLastOutStack(TreeNode root) {
            Stack<TreeNode> stack1 = new Stack<>();
            Stack<TreeNode> stack2 = new Stack<>();
            if (root != null) {
                stack1.push(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()) {
                    System.out.print(stack2.pop().data + "	");
                }
            }
        }
    
        /**
         * 二叉树广度优先遍历(层序遍历)
         *
         * @param root
         */
        private static void levelOrderTraversal(TreeNode root) {
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while (!queue.isEmpty()) {
                TreeNode node = queue.poll();
                System.out.print(node.data + "	");
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
    
    
        public static void main(String[] args) {
            LinkedList linkedList = new LinkedList<Integer>(Arrays.asList(new Integer[]{3, 2, 9, null, null, 10, null, null, 8, null, 4}));
            TreeNode node = createTreeNode(linkedList);
            System.out.println("前序遍历...");
            preOut(node);
            System.out.println();
    
            System.out.println("借助栈实现前序遍历01...");
            preOutStack(node);
            System.out.println();
    
            System.out.println("借助栈实现前序遍历02...");
            doPreOutStack(node);
            System.out.println();
    
            System.out.println("中序遍历...");
            midOut(node);
            System.out.println();
    
            System.out.println("中序遍历Stack...");
            doMidOutStack(node);
            System.out.println();
    
    
            System.out.println("后序遍历...");
            lastOut(node);
            System.out.println();
    
            System.out.println("后序遍历Stack...");
            doLastOutStack(node);
            System.out.println();
    
            System.out.println("广度优先遍历...");
            levelOrderTraversal(node);
        }
    
    }

    执行结果如下:

    前序遍历...
    3 2 9 10 8 4
    借助栈实现前序遍历01...
    3 2 9 10 8 4
    借助栈实现前序遍历02...
    3 2 9 10 8 4
    中序遍历...
    9 2 10 3 8 4
    中序遍历Stack...
    9 2 10 3 8 4
    后序遍历...
    9 10 2 4 8 3
    后序遍历Stack...
    9 10 2 4 8 3
    广度优先遍历...
    3 2 8 9 10 4

  • 相关阅读:
    用队列打印杨辉三角
    mysql允许远程连接
    window文件恢复工具
    android 虚拟机没有sd卡
    StringUtils 的填充方法
    plsql 中出现 Dynamic Performance Tables not accessible 问题解决
    oracle数据库服务介绍
    遮罩的使用
    <pre>标签
    总结五个小技巧定位数据库性能问题
  • 原文地址:https://www.cnblogs.com/huangzhen22/p/15468118.html
Copyright © 2020-2023  润新知