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

    java二叉树遍历,最复杂的是非递归的后序遍历

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.LinkedList;
    
    public class BinaryTree<T> {
        private BinaryNode<T> root;
    
        public BinaryTree(BinaryNode<T> root) {
            this.root = root;
        }
    
        public BinaryTree() {
            this.root = null;
        }
    
        public boolean isEmpty() {
            return this.root == null;
        }
    
        public BinaryNode<T> leftChild() {
            return this.root.left;
        }
    
        public BinaryNode<T> rightChild() {
            return this.root.right;
        }
    
        public void setRoot(BinaryNode<T> root) {
            this.root = root;
        }
    
        public void setLeft(BinaryNode<T> left) {
            this.root.left = left;
        }
    
        public void setRight(BinaryNode<T> right) {
            this.root.right = right;
        }
    
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        static class BinaryNode<T> {
            private T data;
            private BinaryNode<T> left;
            private BinaryNode<T> right;
        }
    
        /**
         * 宽度优先遍历
         */
        public void levelOrder(BinaryNode<T> root) {
            java.util.Queue<BinaryNode<T>> queue = new LinkedList<>();
            queue.add(root);
            while (!queue.isEmpty()) {
                BinaryNode<T> node = queue.remove();
                if (node == null) {
                    continue;
                }
                System.out.println(node.data);
                queue.add(node.left);
                queue.add(node.right);
            }
        }
    
        /**
         * 先根遍历-递归实现
         *
         * @param t
         */
        public void preOrder(BinaryNode<T> t) {
            //递归结束条件
            if (t == null) {
                return;
            } else {
                System.out.println(t.data);
            }
            preOrder(t.left);
            preOrder(t.right);
    
        }
    
        /**
         * 中根遍历-递归实现
         *
         * @param t
         */
        public void midOrder(BinaryNode<T> t) {
            if (t == null) {
                return;
            }
            midOrder(t.left);
            System.out.println(t.data);
            midOrder(t.right);
        }
    
        /**
         * 后根遍历-递归实现
         *
         * @param t
         */
        public void postOrder(BinaryNode<T> t) {
            if (t == null) {
                return;
            }
            postOrder(t.left);
            postOrder(t.right);
            System.out.println(t.data);
        }
    
        /**
         * 先根遍历-非递归实现
         * 先根,然后根的左子树,一直向下左子树,此时右子树尚未访问,所有需要先暂存一下
         * 左到头了,此时需要访问最底层的右子树,只需要从栈中取出最后进栈的右子树
         * 拿到右子树之后,又是先根,然后左到底
         * 所以需要使用栈这种后进先出的数据结构
         *
         * @param t
         */
        public void preOrderNoRec(BinaryNode<T> t) {
            java.util.Stack<BinaryNode<T>> stack = new java.util.Stack<>();
            while (t != null || !stack.isEmpty()) {
                while (t != null) {
                    System.out.println(t.data);
                    stack.push(t.right);
                    t = t.left;
                }
                t = stack.pop();
            }
        }
    
        /**
         * 中根遍历-非递归实现
         * 1。先左子树,一直到底,然后根节点,然后根的右子树
         * 2。根的右子树又是新的一轮循环,还是跟1一样的顺序
         *
         * @param t
         */
        public void midOrderNoRec(BinaryNode<T> t) {
            java.util.Stack<BinaryNode<T>> stack = new java.util.Stack<>();
            while (t != null || !stack.isEmpty()) {
                //递归向左
                while (t.left != null) {
                    stack.push(t);
                    t = t.left;
                }
                //如果有左,就左到头,打印最下的左节点
                //如果没有左节点,那么跳过上面的while循环,打印根节点
                System.out.println(t.data);
                //判断是否还有未遍历的根节点,取出然后打印当前根
                if (!stack.isEmpty()) {
                    t = stack.pop();
                    System.out.println(t.data);
                }
                //切到右子树
                t = t.right;
            }
        }
    
        /**
         * 后根遍历-非递归实现
         * 最复杂
         * @param t
         */
        public void postOrderNoRec(BinaryNode<T> t) {
            java.util.Stack<BinaryNode<T>> stack = new java.util.Stack<>();
            while (t != null || !stack.isEmpty()) {
                //t节点入栈
                while (t != null) {
                    stack.push(t);
                    //如果左节点不为空,则递归向左,否则递归向右
                    if (t.left != null) {
                        t = t.left;
                    } else {
                        t = t.right;
                    }
                }
                //直到t到达既没有左也没有右,取出t打印
                t = stack.pop();
                System.out.println(t.data);
                //栈不空,且当前节点是栈顶的左子节点,切换到右子树
                //如果父节点尚未访问,且当前是父节点的左孩子,递归访问父节点的右孩子
                //否则说明本节点是右孩子,结束本轮循环,从栈顶再重新取一个节点开始
                if (!stack.isEmpty() && stack.peek().left == t) {
                    t = stack.peek().right;
                } else {
                    t = null;
                }
            }
        }
    
        public static void main(String[] args) {
            BinaryTree<Integer> tree = new BinaryTree<>();
            BinaryNode<Integer> root = new BinaryNode<>(1, null, null);
            BinaryNode<Integer> leftL = new BinaryNode<>(4, null, null);
            BinaryNode<Integer> leftR = new BinaryNode<>(5, null, null);
            BinaryNode<Integer> left = new BinaryNode<>(2, leftL, leftR);
            BinaryNode<Integer> rightL = new BinaryNode<>(6, null, null);
            BinaryNode<Integer> rightR = new BinaryNode<>(7, null, null);
            BinaryNode<Integer> right = new BinaryNode<>(3, rightL, rightR);
            tree.setRoot(root);
            tree.setLeft(left);
            tree.setRight(right);
            System.out.println("=======levelOrder=========");
            tree.levelOrder(tree.root);
    //        System.out.println("=======preOrder=========");
    //        tree.preOrder(tree.root);
    //        System.out.println("=======midOrder=========");
    //        tree.midOrder(tree.root);
            System.out.println("=======postOrder=========");
            tree.postOrder(tree.root);
    //        System.out.println("=======preOrderNoRec=========");
    //        tree.preOrderNoRec(tree.root);
    //        System.out.println("=========midOrderNoRec===============");
    //        tree.midOrderNoRec(tree.root);
            System.out.println("==========================");
            tree.postOrderNoRec(tree.root);
    
        }
    }
  • 相关阅读:
    【BigData】Java基础_ArrayList的使用
    【BigData】Java基础_构造方法的使用
    【BigData】Java基础_类和对象的基本使用
    【BigData】Java基础_冒泡排序
    【BigData】Java基础_数组
    【BigData】Java基础_循环
    【BigData】Java基础_终端输入2个数字并求和
    Navicat自动断开连接处理方式
    名字修饰约定extern "C"与extern "C++"浅析
    qt study 元对象,属性和反射编程
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15374348.html
Copyright © 2011-2022 走看看