zoukankan      html  css  js  c++  java
  • 二叉树的遍历

    二叉树

    所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。

    遍历方式分别为:先序遍历、中序遍历、后序遍历。

    遍历之前,我们先来创建一棵树。
    首先要声明结点TreeNode类,代码如下:

    public class TreeNode {
        private int val;
        private TreeNode left;
        private TreeNode right;
        public TreeNode() {
        }
    
        public TreeNode(int val) {
            this.val = val;
        }
    
        public TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
         
        // 省略get、set
    }
    

    随机创建一个tree

    public class TreeBuilder {
    
        /**
         *                      1
         *                  /       
         *                 2            3
         *              /              /   
         *             4     5         6     7
         *             /                
         *             8                 9
         * @return
         */
        public static TreeNode randomBuild() {
            TreeNode node8 = new TreeNode(8);
            TreeNode node9 = new TreeNode(9);
            TreeNode node7 = new TreeNode(7);
            TreeNode node6 = new TreeNode(6, null, node9);
            TreeNode node5 = new TreeNode(5);
            TreeNode node4 = new TreeNode(4, node8, null);
            TreeNode node3 = new TreeNode(3, node6, node7);
            TreeNode node2 = new TreeNode(2, node4, node5);
            TreeNode node1 = new TreeNode(1, node2, node3);
    
            return node1;
        }
    
    }
    

    使用递归的方式进行遍历

    public class TreePrint1 {
    
        public static void main(String[] args) {
            TreeNode head = TreeBuilder.randomBuild();
    
            System.out.println("preorderTraversal");
            preorderTraversal(head);
    
            System.out.println("
    
    inorderTraversal");
            inorderTraversal(head);
    
            System.out.println("
    
    postorderTraversal");
            postorderTraversal(head);
        }
    
        /**
         * 二叉树前序遍历   根-> 左-> 右
         */
        private static void preorderTraversal(TreeNode head) {
            if (head == null) {
                return;
            }
            System.out.print(head.getVal() + " ");
            preorderTraversal(head.getLeft());
            preorderTraversal(head.getRight());
        }
    
        /**
         *  二叉树中序遍历   左-> 根-> 右
         */
        private static void inorderTraversal(TreeNode head) {
            if (head == null) {
                return;
            }
            inorderTraversal(head.getLeft());
            System.out.print(head.getVal() + " ");
            inorderTraversal(head.getRight());
        }
    
        /**
         * 二叉树后序遍历   左-> 右-> 根
         */
        private static void postorderTraversal(TreeNode head) {
            if (head == null) {
                return;
            }
            postorderTraversal(head.getLeft());
            postorderTraversal(head.getRight());
            System.out.print(head.getVal() + " ");
        }
    
    }
    

    使用非递归的方式进行遍历

    public class TreePrint2 {
    
        public static void main(String[] args) {
            TreeNode head = TreeBuilder.randomBuild();
    
            System.out.println("preorderTraversal");
            preorderTraversal(head);
    
            System.out.println("
    
    inorderTraversal");
            inorderTraversal(head);
    
            System.out.println("
    
    postorderTraversal");
            postorderTraversal(head);
        }
    
        /**
         * 二叉树前序遍历   根-> 左-> 右
         */
        private static void preorderTraversal(TreeNode head) {
            if (head == null) {
                return;
            }
            Stack<TreeNode> stack = new Stack<>();
            TreeNode node = head;
            while (node != null || !stack.isEmpty()) {
                while (node != null) {
                    System.out.print(node.getVal() + " ");
                    stack.push(node);
                    node = node.getLeft();
                }
                if (!stack.isEmpty()) {
                    node = stack.pop().getRight();
                }
            }
        }
    
        /**
         *  二叉树中序遍历   左-> 根-> 右
         */
        private static void inorderTraversal(TreeNode head) {
            if (head == null) {
                return;
            }
            Stack<TreeNode> stack = new Stack<>();
            TreeNode node = head;
            while (node != null || !stack.isEmpty()) {
                while (node != null) {
                    stack.push(node);
                    node = node.getLeft();
                }
                if (!stack.isEmpty()) {
                    node = stack.pop();
                    System.out.print(node.getVal() + " ");
                    node = node.getRight();
                }
            }
        }
    
        /**
         * 二叉树后序遍历   左-> 右-> 根
         */
        private static void postorderTraversal(TreeNode head) {
            if (head == null) {
                return;
            }
            Stack<TreeNode> stack = new Stack<>();
            TreeNode node = head;   // 当前根节点
            TreeNode last = null;   // 上一次打印的节点
            while (node != null || !stack.isEmpty()) {
                while (node != null) {
                    stack.push(node);
                    node = node.getLeft();
                }
                if (!stack.isEmpty()) {
                    node = stack.pop();
                    /*
                    没有右节点,当前节点可以打印了
                    当前节点的右节点就是上一次打印的节点,当前节点可以打印了
                    “node = null”表示当前节点的这个分支不能再处理了,因为外层循环是“node = node.getLeft()”
                     */
                    if (node.getRight() == null || node.getRight() == last) {
                        System.out.print(node.getVal() + " ");
                        last = node;
                        node = null;
                    }else {
                        stack.add(node);
                        node = node.getRight();
                    }
    
                }
            }
        }
    
    }
    

    __EOF__

     


     

    欢迎转载,但请注明出处!
    欢迎大家一起交流学习!如果有什么疑问,大家可以在评论区一起交流!
    如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是我的最大动力!

  • 相关阅读:
    矩阵
    手机APP和WAP版的区别
    学习的方法
    ASP.Net中jQuery控制div弹出框效果
    SQL SERVER字符串前加N转换为Unicode编码
    塞尔维亚国家简称编码
    VS2019项目模板中没有[ASP.NET空网站]的解决方案
    Scopus论文数据爬虫
    采集科研文献和数据,我告诉你一个能自动采集的黑科技
    CiteSpace入门教程
  • 原文地址:https://www.cnblogs.com/powercto/p/14354808.html
Copyright © 2011-2022 走看看