zoukankan      html  css  js  c++  java
  • 二叉树(一)

    求二叉树中的节点个数

    求二叉树的深度

    前序遍历

    中序遍历

    后序遍历

    分层遍历

    二叉树分层左右交替遍历(先从左到右,再从右到左,交替)

    求二叉树第K层的节点个数

    二叉树中叶子节点的个数

    判断两棵二叉树是否相同

    判断两个树是否互相镜像

    求二叉树的镜像

    求二叉树中的节点个数

    递归

    /**
     * 求二叉树中的节点个数递归解法: O(n) 
     * (1)如果二叉树为空,节点个数为0 
     * (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1
     */
    public int getNodeNumRec(TreeNode root) {
        if (root == null) {
            return 0;
        } else {
            return getNodeNumRec(root.left) + getNodeNumRec(root.right) + 1;
        }
    }

    迭代

    public int getNodeNum(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int count = 1;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.remove();
            if (node.left != null) {
                queue.add(node.left);
                count++;
            }
            if (node.right != null) {
                queue.add(node.right);
                count++;
            }
        }
        return count;
    }

     求二叉树的深度

    递归

    /**
     * 求二叉树的深度递归解法: O(n) 
     * (1)如果二叉树为空,二叉树的深度为0 
     * (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1
     */
    public int getDepthRec(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int left = getDepthRec(root.left);
        int right = getDepthRec(root.right);
        return Math.max(left, right) + 1;
    }

    遍历

    public int getDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        
        int level = 0;
        int currentLevelNode = 1;
        int nextLevelNode = 0;
        
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.remove();
            currentLevelNode--;
            if (node.left != null) {
                nextLevelNode++;
                queue.add(node.left);
            }
            if (node.right != null) {
                nextLevelNode++;
                queue.add(node.right);
            }
    
            if (currentLevelNode == 0) {
                level++;
                currentLevelNode = nextLevelNode;
                nextLevelNode = 0;
            }
        }
        return level;
    }

     前序遍历

    递归

    /**
     *  前序遍历递归解法: 
     * (1)如果二叉树为空,空操作 
     * (2)如果二叉树不为空:访问根节点,前序遍历左子树,前序遍历右子树
     */
    public void preorderTraversalRec(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.println(root.val);
        preorderTraversalRec(root.left);
        preorderTraversalRec(root.right);
    }
    
    //return list
    ArrayList<Integer> list = new ArrayList<>(); 
    public ArrayList<Integer> preorderTraversalRec(TreeNode root){
        if(root==null){
            return list;
        }
        list.add(root.val);
        preorderTraversalRec(root.left);
        preorderTraversalRec(root.right);
        return list;
    }

     非递归

    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<>();  
        if (root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode cur = stack.pop();
            list.add(cur.val);
    
            if (cur.right != null) {
                stack.push(cur.right);
            }
            if (cur.left != null) {
                stack.push(cur.left);
            }
        }
        return list;
    }

     中序遍历

     递归

    /**
     *  中序遍历递归解法 
     * (1)如果二叉树为空,空操作。 
     * (2)如果二叉树不为空:中序遍历左子树,访问根节点,中序遍历右子树
     */
    public void inorderTraversalRec(TreeNode root) {
        if (root == null) {
            return;
        }
        inorderTraversalRec(root.left);
        System.out.println(root.val);
        inorderTraversalRec(root.right);
    }

     非递归

    public static ArrayList<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode cur = root;
        while (true) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            
            if (stack.isEmpty()) {
                break;
            }
    
            cur = stack.pop();
            list.add(cur.val);
            cur = cur.right;
        }
        return list;
    }

     后序遍历

     递归

    public void postorderTraversalRec(TreeNode root) {
        if (root == null) {
            return;
        }
        postorderTraversal(root.left);
        postorderTraversal(root.right);
        System.out.println(root.val);
    }

     非递归

    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Stack<TreeNode> s = new Stack<TreeNode>(); // 第一个stack用于添加node和它的左右孩子
        Stack<TreeNode> output = new Stack<TreeNode>();// 第二个stack用于翻转第一个stack输出
        s.push(root);
        while (!s.isEmpty()) { // 确保所有元素都被翻转转移到第二个stack
            TreeNode cur = s.pop(); 
            output.push(cur);
            // 把栈顶元素的左孩子和右孩子分别添加入第一个stack
            if (cur.left != null) { 
                s.push(cur.left);
            }
            if (cur.right != null) {
                s.push(cur.right);
            }
        }
    
        while (!output.isEmpty()) { // 遍历输出第二个stack,即为后序遍历
            list.add(output.pop().val);
        }
        return list;
    }

     分层遍历

     递归

    public ArrayList<ArrayList<Integer>> levelTraversalRec(TreeNode root) {
        ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();
        dfs(root, 0, ret);
        return ret;
    }
    private void dfs(TreeNode root, int level, ArrayList<ArrayList<Integer>> ret) {
        if (root == null) {
            return;
        }
        // 添加一个新的ArrayList表示新的一层
        if (level >= ret.size()) {
            ret.add(new ArrayList<Integer>());
        }
        ret.get(level).add(root.val); // 把节点添加到表示那一层的ArrayList里
        dfs(root.left, level + 1, ret); // 递归处理下一层的左子树和右子树
        dfs(root.right, level + 1, ret);
    }

     非递归

    public ArrayList<Integer> levelTraversal(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode cur = queue.remove();
            list.add(cur.val);
            if (cur.left != null) {
                queue.add(cur.left);
            }
            if (cur.right != null) {
                queue.add(cur.right);
            }
        }
        return list;
    }

     

     二叉树分层左右交替遍历(先从左到右,再从右到左,交替) 

    public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
        if(root == null){
            return result;
        }
        
        // 出栈顺序是从左到右
        Stack<TreeNode> leftstack = new Stack<TreeNode>();
        leftstack.push(root);
        
        // 出栈顺序是从右到左
        Stack<TreeNode> rightstack = new Stack<TreeNode>();
        
        boolean left = true;
        
        while(!leftstack.empty() || !rightstack.empty()){
            ArrayList<Integer> list = new ArrayList<Integer>();
            
            if(left){
                int size = leftstack.size();
                for(int i=0; i<size; i++){
                    TreeNode node = leftstack.pop();
                    list.add(node.val);
                    if(node.left!=null){
                        rightstack.push(node.left);
                    }
                    if(node.right!=null){
                        rightstack.push(node.right);
                    }
                }
            }else{
                int size = rightstack.size();
                for(int i=0;i<size;i++){
                    TreeNode node = rightstack.pop();
                    list.add(node.val);
                    if(node.right!=null){
                        leftstack.push(node.right);
                    }
                    if(node.left!=null){
                        leftstack.push(node.left);
                    }
                }
            }
            
            left=!left;
            result.add(list);
        }
        return result;
    } 

     求二叉树第K层的节点个数

     递归:求以root为根的第k层节点数目 == 求以root.left 为根的k-1层(因为少了root那一层)节点数目 + 以root.right 为根的k-1层节点数目

    /**
     *  求二叉树第K层的节点个数 递归解法: 
     * (1)如果二叉树为空或者k<1返回0 
     * (2)如果二叉树不为空并且k==1,返回1 
     * (3)如果二叉树不为空且k>1,返回root左子树中k-1层的节点个数与root右子树k-1层节点个数之和
     */
    public int getNodeNumKthLevelRec(TreeNode root, int k) {
        if (root == null || k < 1)
            return 0;
        if (k == 1) 
            return 1;
    int numLeft = getNodeNumKthLevelRec(root.left, k - 1); int numRight = getNodeNumKthLevelRec(root.right, k - 1); return numLeft + numRight; }

     非递归

    // 与求二叉树深度迭代方法一样
    public int getNodeNumKthLevel(TreeNode root, int k) {
        if (root == null) {
            return 0;
        }
    
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        int i = 0;
        int currentLevelNodes = 1;
        int nextLevelNodes = 0;
    
        queue.add(root);
        while (!queue.isEmpty() && i < k) {
            TreeNode cur = queue.remove();
            currentLevelNodes--;
            if (cur.left != null) {
                queue.add(cur.left);
                nextLevelNodes++;
            }
            if (cur.right != null) {
                queue.add(cur.right);
                nextLevelNodes++;
            }
    
            if (currentLevelNodes == 0) { 
                currentLevelNodes = nextLevelNodes;
                nextLevelNodes = 0;
                i++;
            }
        }
        return currentLevelNodes;
    }

     

     二叉树中叶子节点的个数

     递归

    public int getNodeNumLeafRec(TreeNode root) {
        if (root == null)
            return 0;
        if (root.left == null && root.right == null)
            return 1;
        
        return getNodeNumLeafRec(root.left) + getNodeNumLeafRec(root.right);
    }

     非递归

    // 基于分层遍历方法
    public int getNodeNumLeaf(TreeNode root) {
        if (root == null) {
            return 0;
        }
    
        int leafNodes = 0;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
    
        while (!queue.isEmpty()) {
            TreeNode cur = queue.remove();
            if (cur.left != null) {
                queue.add(cur.left);
            }
            if (cur.right != null) {
                queue.add(cur.right);
            }
            if (cur.left == null && cur.right == null) {
                leafNodes++;
            }
        }
        return leafNodes;
    }

     

     判断两棵二叉树是否相同

     递归

    /**
     *  判断两棵二叉树是否相同的树。 递归解法: 
     * (1)如果两棵二叉树都为空,返回真 
     * (2)如果两棵二叉树一棵为空,另一棵不为空,返回假
     * (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都相同返回真,其他返回假
     */
    public boolean isSameRec(TreeNode t1, TreeNode t2){
        if(t1==null && t2==null){
            return true;
        }
        if(t1==null || t2==null){
            return false;
        }
        if(t1.val==t2.val){
            return isSameRec(t1.left, t2.left) && isSameRec(t2.right, t2.right);
        }
        return false;
    }

     非递归

    /**
     *  判断两棵二叉树是否相同的树(迭代) 遍历一遍即可,这里用preorder
     */
    public boolean isSame(TreeNode r1, TreeNode r2) {
        if (r1 == null && r2 == null) {
            return true;
        } else if (r1 == null || r2 == null) {
            return false;
        }
    
        Stack<TreeNode> s1 = new Stack<TreeNode>();
        Stack<TreeNode> s2 = new Stack<TreeNode>();
        s1.push(r1);
        s2.push(r2);
    
        while (!s1.isEmpty() && !s2.isEmpty()) {
            TreeNode node1 = s1.pop();
            TreeNode node2 = s2.pop();
            if (node2 == null && node1 == null) {
                continue;
            } else if (node1 != null && node2 != null && node1.val == node2.val) {
                s1.push(node1.right);
                s1.push(node1.left);
                s2.push(node2.right);
                s2.push(node2.left);
            } else {
                return false;
            }
        }
        return true;
    }

     

     判断两个树是否互相镜像

    public boolean isMirrorRec(TreeNode r1, TreeNode r2) {
        if (r1 == null && r2 == null) {
            return true;
        }
        if (r1 == null || r2 == null) {
            return false;
        }
    
        if (r1.val != r2.val) {
            return false;
        }
    
        return isMirrorRec(r1.left, r2.right) && isMirrorRec(r1.right, r2.left);
    }

     

     求二叉树的镜像

     递归

    public TreeNode mirrorCopyRec(TreeNode root) {
        if (root == null) {
            return null;
        }
    
        TreeNode newNode = new TreeNode(root.val);
        newNode.left = mirrorCopyRec(root.right);
        newNode.right = mirrorCopyRec(root.left);
        return newNode;
    }

     非递归

    // 1. 破坏原来的树,把原来的树改成其镜像
    public void mirror(TreeNode root) {
        if (root == null) {
            return;
        }
    
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode cur = stack.pop();
    
            TreeNode temp = cur.left;
            cur.right = cur.left;
            cur.left = temp;
    
            if (cur.right != null) {
                stack.push(cur.right);
            }
            if (cur.left != null) {
                stack.push(cur.left);
            }
        }
    }
    
    // 2. 不破坏原来的树,返回一个新的镜像树
    public static TreeNode mirrorCopy(TreeNode root) {
        if (root == null) {
            return root;
        }
    
        Stack<TreeNode> stack = new Stack<TreeNode>();
        Stack<TreeNode> newStack = new Stack<TreeNode>();
        stack.push(root);
        TreeNode newRoot = new TreeNode(root.val);
        newStack.push(newRoot);
    
        while (!stack.isEmpty()) {
            TreeNode cur = stack.pop();
            TreeNode newCur = newStack.pop();
    
            if (cur.right != null) {
                stack.push(cur.right);
                newCur.left = new TreeNode(cur.right.val);
                newStack.push(newCur.left);
            }
            if (cur.left != null) {
                stack.push(cur.left);
                newCur.right = new TreeNode(cur.left.val);
                newStack.push(newCur.right);
            }
        }
        return newRoot;
    }
  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/hesier/p/5572869.html
Copyright © 2011-2022 走看看