树递归算法要点精析
Posted zqiguoshang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树递归算法要点精析相关的知识,希望对你有一定的参考价值。
树的递归脱不了三种递归遍历的范畴。所以看到树的递归算法,先想清楚是哪种遍历,需要哪种遍历,这可大大降低复杂度。
虽然遍历过程,每个节点会走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); } }
以上是关于树递归算法要点精析的主要内容,如果未能解决你的问题,请参考以下文章