zoukankan      html  css  js  c++  java
  • 二叉树(构建、先序、中序、后序、层序(递归,非递归)遍历,求树的深度)

    二叉树构造类

        /**
         * 二叉树类
         * @日期: 2018年6月12日 下午10:37:49
         * @作者: Chendb
         */
        class TreeNode {
    
            // 节点值
            private int val = 0;
            
            // 左子树
            private TreeNode left = null;
            
            // 右子树
            private TreeNode right = null;
            
            public TreeNode (int val) {
                this.val = val;
                this.left = null;
                this.right = null;
            }
    
            public TreeNode() {
                
            }
            
            public int getVal() {
                return val;
            }
    
            public void setVal(int val) {
                this.val = val;
            }
    
            public TreeNode getLeft() {
                return left;
            }
    
            public void setLeft(TreeNode left) {
                this.left = left;
            }
    
            public TreeNode getRight() {
                return right;
            }
    
            public void setRight(TreeNode right) {
                this.right = right;
            }
        }

    构造二叉树

         /**
         * 创建一颗二叉树
         * @param array 构建二叉树的数据数组
         * @return 二叉树
         */
        public TreeNode createBinaryTree(int[] array) {
            
            if (array == null || array.length == 0) {
                return new TreeNode();
            }
            
            LinkedList<TreeNode> nodeList = new LinkedList<>();
            for (int i = 0; i < array.length; i++) {
                nodeList.add(new TreeNode(array[i]));
            }
            
            for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) {
                //左子树
                nodeList.get(parentIndex).left = nodeList.get(parentIndex * 2 + 1);
                //右子树
                nodeList.get(parentIndex).right = nodeList.get(parentIndex * 2 + 2);
            }
            
            // 最后一个父节点可能没有右子树
            int lastParentIndex = array.length / 2 - 1;
            nodeList.get(lastParentIndex).left = nodeList.get(lastParentIndex * 2 + 1);
            
            // 当为奇数时,最后一个父节点有右子树
            if (array.length % 2 == 1) {
                nodeList.get(lastParentIndex).right = nodeList.get(lastParentIndex * 2 + 2);
            }
            
            return nodeList.get(0);
        }

    先序遍历(递归)

        /**
         * 先序遍历(递归)
         * @param root 根节点
         */
        public void preOrderTraverseByRecursion(TreeNode root) {
            if (root == null) {
                return ;
            }
            
            // 先访问根节点
            System.out.println(root.getVal());
            // 次访问左子树
            preOrderTraverseByRecursion(root.getLeft());
            // 后访问右子树
            preOrderTraverseByRecursion(root.getRight());
        }           

    先序遍历

        /**
         * 先序遍历
         * @param root 根节点
         */
        public void preOrderTraverse(TreeNode root) {
            if (root == null) {
                return;
            }
            
            Stack<TreeNode> stack = new Stack<TreeNode>();
            stack.push(root);
            
            // 利用栈的先进后出特性进行遍历
            while (!stack.isEmpty()) {
                
                TreeNode treeNode = stack.pop();
                // 先访问根节点
                System.out.println(treeNode.getVal());
                
                if ( treeNode.getRight() != null) {
                    // 放入右节点
                    stack.push(treeNode.getRight());
                }
                
                if ( treeNode.getLeft() != null) {
                    // 放入左节点
                    stack.push(treeNode.getLeft());
                }
            }
        }

    中序遍历(递归)

        /**
         * 中序遍历(递归)
         * @param root 根节点
         */
        public void inOrderTraverseByRecursion(TreeNode root) {
            if (root == null) {
                return ;
            }
            
            // 先次访问左子树
            inOrderTraverseByRecursion(root.getLeft());
            // 次访问根节点
            System.out.println(root.getVal());
            // 后访问右子树
            inOrderTraverseByRecursion(root.getRight());
        }

    中序遍历

        /**
         * 中序遍历
         * @param root 根节点
         */
        public void inOrderTraverse(TreeNode root) {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            
            TreeNode treeNode = root ;
            
            // 利用栈的先进后出特性进行遍历
            while (treeNode != null || !stack.isEmpty()) {
                
                // 存在左子树
                while (treeNode != null) {
                    stack.push(treeNode);
                    treeNode = treeNode.getLeft();
                }
                
                // 栈非空
                if (!stack.isEmpty()) {
                    treeNode = stack.pop();
                    System.out.println(treeNode.getVal());
                    treeNode = treeNode.getRight();
                }
            }
        }

    后序遍历(递归)

        /**
         * 后序遍历(递归)
         * @param root 根节点
         */
        public void afterOrderTraverseByRecursion(TreeNode root) {
            if (root == null) {
                return ;
            }
            
            // 后访问左子树
            afterOrderTraverseByRecursion(root.getLeft());
            // 次访问右子树
            afterOrderTraverseByRecursion(root.getRight());
            // 先访问根节点
            System.out.println(root.getVal());
        }

    后序遍历

        /**
         * 后序遍历
         * @param root 根节点
         */
        public void afterOrderTraverse(TreeNode root) {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            
            // 用来记录被访问的节点
            TreeNode visitNode = root ;
            TreeNode treeNode = root ;
            
            // 利用栈的先进后出特性进行遍历
            while (treeNode != null) {
                
                // 左子树入栈
                for (;treeNode.getLeft() != null ;treeNode = treeNode.getLeft()) {
                    stack.push(treeNode);
                }
                
                // 当前节点没有右子树或者右子树已经被访问
                while (treeNode != null && (treeNode.getRight() == null || treeNode.getRight() == visitNode)) {
                    System.out.println(treeNode.getVal());
                    // 记录上一个被访问的节点
                    visitNode = treeNode;
                    if (stack.isEmpty()) {
                        return;
                    }
                    treeNode = stack.pop();
                }
                
                // 处理右子树
                stack.push(treeNode);
                treeNode = treeNode.getRight();
            }
        }

    层序遍历(递归)

        /**
         * 层序遍历(递归)
         * @param root 根节点
         */
        public void levelOrderTraverseByRecursion(TreeNode root) {
            if (root == null) {
                return;
            }
    
            int depth = getBinaryTreeDepthByRecursion(root);
    
            for (int i = 1; i <= depth; i++) {
                levelOrderTraverse(root, i);
            }
        }
        
        private void levelOrderTraverse(TreeNode treeNode,int level){
            if (treeNode == null || level < 1) {
                return;
            }
    
            if (level == 1) {
                System.out.println(treeNode.getVal());
                return;
            }
    
            // 访问左子树
            levelOrderTraverse(treeNode.getLeft(), level - 1);
    
            // 右子树
            levelOrderTraverse(treeNode.getRight(), level - 1);
        }

    层序遍历

        /**
         * 层序遍历
         * @param root 根节点
         */
        public void levelOrderTraverse(TreeNode root) {
            if (root == null) {
                return ;
            }
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while (!queue.isEmpty()) {
                TreeNode treeNode = queue.poll();
                System.out.println(treeNode.getVal());
                if (treeNode.getLeft() != null) {
                    queue.offer(treeNode.getLeft());
                }
                if (treeNode.getRight() != null) {
                    queue.offer(treeNode.getRight());
                }
            }
        }

    树的深度(递归)

        /**
         * 获取二叉树的深度(递归)
         * @param root 根节点
         * @return 二叉树的深度
         */
        public int getBinaryTreeDepthByRecursion(TreeNode root) {
            
            if (root == null) {
                return 0;
            }
            
            int l = getBinaryTreeDepthByRecursion(root.left);
            int r = getBinaryTreeDepthByRecursion(root.right);
            
            if (l > r) {
                return l + 1;
            }
            
            return r + 1;
        }

    树的深度

        /**
         * 获取二叉树的深度
         * @param root 根节点
         * @return 二叉树深度
         */
        public int getBinaryTreeDepth(TreeNode root) {
            if (root == null) {
                return 0;
            }
            
            int depth = 0 ;
            
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while (!queue.isEmpty()) {
                int len = queue.size();
                depth++;
                while (len > 0) {
                    TreeNode treeNode = queue.element();
                    queue.poll();
                    if (treeNode.getLeft() != null) {
                        queue.offer(treeNode.getLeft());
                    }
                    if(treeNode.getRight() != null) {
                        queue.offer(treeNode.getRight());
                    }
                    len--;
                }
            }
            return depth;
        }

     测试

    public static void main(String[] args) {
            int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
            BinaryTree binaryTree = new BinaryTree();
            TreeNode root = binaryTree.createBinaryTree(array);
            System.out.println("前序遍历(递归):");
            binaryTree.preOrderTraverseByRecursion(root);
            System.out.println("前序遍历:");
            binaryTree.preOrderTraverse(root);
            
            System.out.println("中序遍历(递归):");
            binaryTree.inOrderTraverseByRecursion(root);
            System.out.println("中序遍历:");
            binaryTree.inOrderTraverse(root);
            
            System.out.println("后序遍历(递归):");
            binaryTree.afterOrderTraverseByRecursion(root);
            System.out.println("后序遍历:");
            binaryTree.afterOrderTraverse(root);
            
            System.out.println("层序遍历(递归):");
            binaryTree.levelOrderTraverseByRecursion(root);
            System.out.println("层序遍历:");
            binaryTree.levelOrderTraverse(root);
            
            int depth = binaryTree.getBinaryTreeDepthByRecursion(root);
            System.out.println("树的深度(递归):" + depth);
            depth = binaryTree.getBinaryTreeDepth(root);
            System.out.println("树的深度:" + depth);
        }
  • 相关阅读:
    读《大道至简》第六章感想
    课后作业之数组
    读《大道至简》第五章感想
    课后作业四
    读《大道至简》第四章之感想
    java上课作业(第三次)
    读《大道至简》第三章感想
    作业
    小组项目冲刺第三天的个人总结
    小组项目冲刺第二天的个人总结
  • 原文地址:https://www.cnblogs.com/cdblogs/p/9219395.html
Copyright © 2011-2022 走看看