二叉树(构建、先序、中序、后序、层序(递归,非递归)遍历,求树的深度)

二叉树构造类

    /**
     * 二叉树类
     * @日期: 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);
    }

 

posted @ 2018-06-24 00:43  无聊的小剑  阅读(856)  评论(0编辑  收藏  举报