• 树递归算法要点精析


    树的递归脱不了三种递归遍历的范畴。所以看到树的递归算法,先想清楚是哪种遍历,需要哪种遍历,这可大大降低复杂度。

    虽然遍历过程,每个节点会走3遍,但实际访问就一遍。所以在递归结束判断中,最好每层只判断当前节点。

    在整层递归中,每一层要把一层的事情做完,然后将结果返回上一层。这样也便于判断正误。

    由于递归是深度优先执行,我们无法保证广度方向的同层性。所以如果需要广度方向的同层性保证,要引入辅助数组。

    最后,适当的添加辅助参数,如层次等信息,可极大简化算法。

    下面给出几个递归算法:

       /**
         * count the number of leaves in a tree.
         * @param root Node root of tree
         * @return int  leaves number
         */
        public static int numOfLeaves(Node root){
            if (root == null) return 0;
            if (root.left == null && root.right == null) return 1;
            return numOfLeaves(root.left) + numOfLeaves(root.right);
        }
    
        /**
         * change all the left sub-tree and right sub-tree position in the tree.
         * @param root
         */
        public static void changeLeftAndRight(Node root){
            if (root != null){
                changeLeftAndRight(root.left);
                changeLeftAndRight(root.right);
                Node tmp = root.left;
                root.left = root.right;
                root.right = tmp;
            }
        }
    
        /**
         * count the number of node whose degree is 1
         * @param root number
         */
        public static int numOf1degree(Node root){
            if (root == null) return 0;
            int sum = numOf1degree(root.left) + numOf1degree(root.right);
            if (root.right == null && root.left != null || root.left == null && root.right != null) return sum + 1;
            return sum;
        }
    
        /**
         * count the number of nodes whose degree are 2.
         * @param root
         * @return number
         */
        public static int numOf2degree(Node root){
            if (root == null) return 0;
            int sum = numOf2degree(root.left) + numOf2degree(root.right);
            if (root.right != null && root.left != null) return sum + 1;
            return sum;
        }
    
        public static int numOf0degree(Node root){
            if (root == null) return 0;
            if (root.right == null && root.left == null) return 1;
            return numOf0degree(root.left) + numOf0degree(root.right);
        }
    
        /**
         * return the deep of the tree.
         * @param root
         * @return  deep of tree
         */
        public static int deepOfTree(Node root){
            if (root == null) return 0;
            int left = deepOfTree(root.left);
            int right = deepOfTree(root.right);
            return left > right ? left + 1 : right + 1;
        }
    
        /**
         * return width of the tree. we have a wideArray which stores every level width of the tree.
         * what we need to do is find the max width.
         * @param root root of the tree
         * @return width of tree
         */
        public static int wideOfTree(Node root){
            int[] wideArray = new int[20];
            wideOfTree(root, wideArray,0);
            int max = 0;
            for (int i: wideArray) {
                if (i > max){
                    max = i;
                }
            }
            return max;
        }
    
        /**
         * private width of tree
         * Recursion is deep first traversal. But calculate the width of tree is hierarchical operation.
         * Without extra help, we cannot guarantee the recursion nodes are in the same level.
         * @param root root of tree
         * @param wideArray we need to store the width of every level. so we need a wideArray to help.
         * @param level level of root
         */
        public static void wideOfTree(Node root, int[] wideArray, int level){
            if (root != null){
                wideArray[level] += 1;
                wideOfTree(root.left, wideArray, level+1);
                wideOfTree(root.right, wideArray, level+1);
            }
        }
    
    
        /**
         * return the level of the specified node.
         * @param root root of the tree.
         * @param p the specified node
         * @param level the level of root
         * @return the level of the specified node
         */
        public static int levelOfP(Node root, Node p, int level){
            if (root == null) return 0;
            if (root == p) return level + 1;
            int left = levelOfP(root.left, p, level+1);
            int right = levelOfP(root.right, p, level+1);
            return left > right ? left : right;
        }
    
        /**
         * delete all leaf nodes of the tree
         * @param root the root of the tree
         */
        public static void deleteAllLeaves(Node root){
            if (root == null) return;
            if (root.left == null && root.right == null) {
                root = null;
                return;
            }
            deepOfTree(root.left);
            deepOfTree(root.right);
        }
    
        /**
         * use suffix traversal to realize the function.
         * In every recursion level , return the max of the parent value and the sub-tree value.
         * return the value of the node which has the max value
         * @param root root of the tree
         * @param lastMax the max value of parent node. should be initialized by Integer.MIN_VALUE
         * @return the max node value of the tree
         */
        public static int valueOfMaxNode(Node root, int lastMax){
            if (root == null) return lastMax;
            if (root.value > lastMax) lastMax = root.value;
            int maxLeft = valueOfMaxNode(root.left, lastMax);
            int maxRight = valueOfMaxNode(root.right, lastMax);
            return maxLeft > maxRight ? maxLeft : maxRight;
        }
    
        public static void printNodeInfoByInfixTraversal(Node root, int level) {
            if (root != null){
                System.out.print("( "+ root.value + " " + level + ") ");
                printNodeInfoByInfixTraversal(root.left, level+1);
                printNodeInfoByInfixTraversal(root.right, level+1);
            }
        }
    

      

  • 相关阅读:
    SonarQube+Jenkins代码审查集成CI/CD
    “拒绝了对对象'aspnet_CheckSchemaVersion'的 EXECUTE 权限”之解决
    ORA-31687: error creating worker process with worker id 1
    Oracle修改表列长度
    RouYi(Export excel)
    Spring事务失效的原因
    Linux/Keychron键盘 功能键F1-F12映射修复
    git 推送本地文件到远程仓库
    git remote 删除已添加的远程仓库地址
    mssql新建数据库
  • 原文地址:https://www.cnblogs.com/zqiguoshang/p/6547569.html
Copyright © 2020-2023  润新知