/* * 判断两棵二叉树是否相同的树。 * 递归解法: * (1)如果两棵二叉树都为空,返回真 * (2)如果两棵二叉树一棵为空,另一棵不为空,返回假 * (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假 * */ public static boolean isSameRec(TreeNode r1, TreeNode r2) { // both are null. if (r1 == null && r2 == null) { return true; } // one is null. if (r1 == null || r2 == null) { return false; } // 1. the value of the root should be the same; // 2. the left tree should be the same. // 3. the right tree should be the same. return r1.val == r2.val && isSameRec(r1.left, r2.left) && isSameRec(r1.right, r2.right); } /* * 判断两棵二叉树是否相同的树。 * 迭代解法 * 我们直接用中序遍历来比较就好啦 * */ public static boolean isSame(TreeNode r1, TreeNode r2) { // both are null. if (r1 == null && r2 == null) { return true; } // one is null. if (r1 == null || r2 == null) { return false; } Stack<TreeNode> s1 = new Stack<TreeNode>(); Stack<TreeNode> s2 = new Stack<TreeNode>(); TreeNode cur1 = r1; TreeNode cur2 = r2; while (true) { while (cur1 != null && cur2 != null) { s1.push(cur1); s2.push(cur2); cur1 = cur1.left; cur2 = cur2.left; } if (cur1 != null || cur2 != null) { return false; } if (s1.isEmpty() && s2.isEmpty()) { break; } cur1 = s1.pop(); cur2 = s2.pop(); if (cur1.val != cur2.val) { return false; } cur1 = cur1.right; cur2 = cur2.right; } return true; }
/*
.public static int getDepthRec(TreeNode root) {//求树高 if (root == null) { return -1; } return Math.max(getDepthRec(root.left), getDepthRec(root.right)) + 1; } /* * 可以用 level LevelOrderTraversal 来实现,我们用一个dummyNode来分隔不同的层,这样即可计算出实际的depth. * 1 / \ 2 3 / \ \ 4 5 6 * * 在队列中如此排列: 1, dummy, 2, 3, dummy, 4, 5, 5, dummy * */ public static int getDepth(TreeNode root) { if (root == null) { return 0; } TreeNode dummy = new TreeNode(0); Queue<TreeNode> q = new LinkedList<TreeNode>(); q.offer(root); q.offer(dummy); int depth = -1; while (!q.isEmpty()) { TreeNode curr = q.poll(); if (curr == dummy) { depth++; if (!q.isEmpty()) { // 使用DummyNode来区分不同的层, 如果下一层不是为空,则应该在尾部加DummyNode. q.offer(dummy); } } if (curr.left != null) { q.offer(curr.left); } if (curr.right != null) { q.offer(curr.right); } } return depth; }
/* * * 判断二叉树是不是平衡二叉树:isAVLRec * 1. 左子树,右子树的高度差不能超过1 * 2. 左子树,右子树都是平衡二叉树。 * */ public static boolean isAVLRec(TreeNode root) { if (root == null) { return true; } // 左子树,右子树都必须是平衡二叉树。 if (!isAVLRec(root.left) || !isAVLRec(root.right)) { return false; } int dif = Math.abs(getDepthRec(root.left) - getDepthRec(root.right)); if (dif > 1) { return false; } return true; }
/* * . 求二叉树中两个节点的最低公共祖先节点: * */ public static TreeNode LACRec(TreeNode root, TreeNode node1, TreeNode node2) { if (root == null || node1 == null || node2 == null) { return null; } // If any of the node is the root, just return the root. if (root == node1 || root == node2) { return root; } // if no node is in the node, just recursively find it in LEFT and RIGHT tree. TreeNode left = LACRec(root.left, node1, node2); TreeNode right = LACRec(root.right, node1, node2); if (left == null) { // If didn't found in the left tree, then just return it from right. return right; } else if (right == null) { // Or if didn't found in the right tree, then just return it from the left side. return left; } // if both right and right found a node, just return the root as the Common Ancestor. return root; }
/* * 求BST中两个节点的最低公共祖先节点: * Recursive version: * LCABst * * 1. If found in the left tree, return the Ancestor. * 2. If found in the right tree, return the Ancestor. * 3. If Didn't find any of the node, return null. * 4. If found both in the left and the right tree, return the root. * */ public static TreeNode LCABstRec(TreeNode root, TreeNode node1, TreeNode node2) { if (root == null || node1 == null || node2 == null) { return null; } // If any of the node is the root, just return the root. if (root == node1 || root == node2) { return root; } int min = Math.min(node1.val, node2.val); int max = Math.max(node1.val, node2.val); // if the values are smaller than the root value, just search them in the left tree. if (root.val > max) { return LCABstRec(root.left, node1, node2); } else if (root.val < min) { // if the values are larger than the root value, just search them in the right tree. return LCABstRec(root.right, node1, node2); } // if root is in the middle, just return the root. return root; }
/* * 算法. 由前序遍历序列和中序遍历序列重建二叉树:rebuildBinaryTreeRec * We assume that there is no duplicate in the trees. * For example: * 1 * / \ * 2 3 * /\ \ * 4 5 6 * /\ * 7 8 * * PreOrder should be: 1 2 4 5 3 6 7 8 * 根 左子树 右子树 * InOrder should be: 4 2 5 1 3 7 6 8 * 左子树 根 右子树 * */ public static TreeNode rebuildBinaryTreeRec(List<Integer> preOrder, List<Integer> inOrder) { if (preOrder == null || inOrder == null) { return null; } // If the traversal is empty, just return a NULL. if (preOrder.size() == 0 || inOrder.size() == 0) { return null; } // we can get the root from the preOrder. // Because the first one is the root. // So we just create the root node here. TreeNode root = new TreeNode(preOrder.get(0)); List<Integer> preOrderLeft; List<Integer> preOrderRight; List<Integer> inOrderLeft; List<Integer> inOrderRight; // 获得在 inOrder中,根的位置 int rootInIndex = inOrder.indexOf(preOrder.get(0)); preOrderLeft = preOrder.subList(1, rootInIndex + 1); preOrderRight = preOrder.subList(rootInIndex + 1, preOrder.size()); // 得到inOrder左边的左子树 inOrderLeft = inOrder.subList(0, rootInIndex); inOrderRight = inOrder.subList(rootInIndex + 1, inOrder.size()); // 通过 Rec 来调用生成左右子树。 root.left = rebuildBinaryTreeRec(preOrderLeft, inOrderLeft); root.right = rebuildBinaryTreeRec(preOrderRight, inOrderRight); return root; }
/* * * 求二叉树第K层的节点个数:getNodeNumKthLevelRec, getNodeNumKthLevel * */ public static int getNodeNumKthLevel(TreeNode root, int k) { if (root == null || k <= 0) { return 0; } int level = 0; Queue<TreeNode> q = new LinkedList<TreeNode>(); q.offer(root); TreeNode dummy = new TreeNode(0); int cnt = 0; // record the size of the level. q.offer(dummy); while (!q.isEmpty()) { TreeNode node = q.poll(); if (node == dummy) { level++; if (level == k) { return cnt; } cnt = 0; // reset the cnt; if (q.isEmpty()) { break; } q.offer(dummy); continue; } cnt++; if (node.left != null) { q.offer(node.left); } if (node.right != null) { q.offer(node.right); } } return 0; }
/* * * 求二叉树第K层的节点个数:getNodeNumKthLevelRec, getNodeNumKthLevel * */ public static int getNodeNumKthLevelRec(TreeNode root, int k) { if (root == null || k <= 0) { return 0; } if (k == 1) { return 1; } // 将左子树及右子树在K层的节点个数相加. return getNodeNumKthLevelRec(root.left, k - 1) + getNodeNumKthLevelRec(root.right, k - 1); }
/* * * 12. 求二叉树中节点的最大距离:getMaxDistanceRec * * 首先我们来定义这个距离: * 距离定义为:两个节点间边的数目. * 如: * 1 * / \ * 2 3 * \ * 4 * 这里最大距离定义为2,4的距离,为3. * 求二叉树中节点的最大距离 即二叉树中相距最远的两个节点之间的距离。 (distance / diameter) * 递归解法: * 返回值设计: * 返回1. 深度, 2. 当前树的最长距离 * (1) 计算左子树的深度,右子树深度,左子树独立的链条长度,右子树独立的链条长度 * (2) 最大长度为三者之最: * a. 通过根节点的链,为左右深度+2 * b. 左子树独立链 * c. 右子树独立链。 * * (3)递归初始条件: * 当root == null, depth = -1.maxDistance = -1; * */ public static int getMaxDistanceRec(TreeNode root) { return getMaxDistanceRecHelp(root).maxDistance; } public static Result getMaxDistanceRecHelp(TreeNode root) { Result ret = new Result(-1, -1); if (root == null) { return ret; } Result left = getMaxDistanceRecHelp(root.left); Result right = getMaxDistanceRecHelp(root.right); // 深度应加1, the depth from the subtree to the root. ret.depth = Math.max(left.depth, right.depth) + 1; // 左子树,右子树与根的距离都要加1,所以通过根节点的路径为两边深度+2 int crossLen = left.depth + right.depth + 2; // 求出cross根的路径,及左右子树的独立路径,这三者路径的最大值。 ret.maxDistance = Math.max(left.maxDistance, right.maxDistance); ret.maxDistance = Math.max(ret.maxDistance, crossLen); return ret; } private static class Result { int depth; int maxDistance; public Result(int depth, int maxDistance) { this.depth = depth; this.maxDistance = maxDistance; } }
/* * .求叶子节点个数 getNodeNumLeafRec 把左子树和右子树的叶子节点加在一起即可 * */ public static 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); }
/* 7. getNodeNumLeaf * 随便使用一种遍历方法都可以,比如,中序遍历。 * inorderTraversal,判断是不是叶子节点。 * */ public static int getNodeNumLeaf(TreeNode root) { if (root == null) { return 0; } int cnt = 0; // we can use inorderTraversal travesal to do it. Stack<TreeNode> s = new Stack<TreeNode>(); TreeNode cur = root; while (true) { while (cur != null) { s.push(cur); cur = cur.left; } if (s.isEmpty()) { break; } // all the left child has been put into the stack, let's deal with the // current node. cur = s.pop(); if (cur.left == null && cur.right == null) { cnt++; } cur = cur.right; } return cnt; }
转自:http://blog.csdn.net/yangcs2009/article/details/40146967
/** * 求二叉树中两个节点的最低公共祖先节点 * 递归解法: * (1)如果两个节点分别在根节点的左子树和右子树,则返回根节点 * (2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树 */ public static TreeNode getLastCommonParentRec(TreeNode root, TreeNode n1, TreeNode n2) { if (findNodeRec(root.left, n1)) { // 如果n1在树的左子树 if (findNodeRec(root.right, n2)) { // 如果n2在树的右子树 return root; // 返回根节点 } else { // 如果n2也在树的左子树 return getLastCommonParentRec(root.left, n1, n2); // 递归处理 } } else { // 如果n1在树的右子树 if (findNodeRec(root.left, n2)) { // 如果n2在左子树 return root; } else { // 如果n2在右子树 return getLastCommonParentRec(root.right, n1, n2); // 递归处理 } } } // 帮助方法,递归判断一个点是否在树里 private static boolean findNodeRec(TreeNode root, TreeNode node) { if (root == null || node == null) { return false; } if (root == node) { return true; } // 先尝试在左子树中查找 boolean found = findNodeRec(root.left, node); if (!found) { // 如果查找不到,再在右子树中查找 found = findNodeRec(root.right, node); } return found; }
二叉树相关算法
最新推荐文章于 2020-06-05 17:39:44 发布