三种情况:(自己写的,不保证所有实例完全通过)
1.树是二叉搜索树的情况;用搜索树的性质进行查找;
2.树是普通二叉树,但是包含父节点;用两个单链表的第一个公共父节点来进行查找;
3.树是多叉树,先用一个方法找到两个节点从根结点到各个节点的路径,在用两个单链表的第一个公共父节点来进行查找;
import java.util.LinkedList; import java.util.Stack; class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int val) { this.val = val; } }
class TreeNodeWithMoreChild { public int val; public TreeNodeWithMoreChild first; public TreeNodeWithMoreChild second; public TreeNodeWithMoreChild third; public TreeNodeWithMoreChild(int val) { this.val = val; } }
class TreeNodeWithMoreChild { public int val; public TreeNodeWithMoreChild first; public TreeNodeWithMoreChild second; public TreeNodeWithMoreChild third; public TreeNodeWithMoreChild(int val) { this.val = val; } } public class FatherNodeForTree50 { /** * 是二叉排序树; * * @param left * @param right * @param root * @return */ public TreeNode getFatherNode(TreeNode left, TreeNode right, TreeNode root) { if(root == null || left == null || right == null) { return null; } else { if(root.val >= left.val && root.val <= right.val) { return root; } else if((root.val > left.val && root.val >= right.val) || (root.val >= left.val && root.val > right.val)) { return getFatherNode(left, right, root.left); } else { return getFatherNode(left, right, root.right); } } } /** * 带有指向父节点的指针的二叉树; * 等于求两个单链表的公共节点; * @param left * @param right * @param root * @return */ public TreeNodeWithFather getFatherNode2(TreeNodeWithFather left, TreeNodeWithFather right) { if(left == null || right == null) { return null; } else { int n1 = 0; int n2 = 0; TreeNodeWithFather p1 = left; TreeNodeWithFather p2 = right; while(p1.father != null) { n1++; p1= p1.father; } while(p2.father != null) { n2++; p2 = p2.father; } int sub = 0; p1 = left; p2 = right; int k = 0; if(n2 > n1) { sub = n2 - n1; while(k < sub) { p2 = p2.father; k++; } } else { k = 0; sub = n1 - n2; while(k < sub) { p1 = p1.father; k++; } } while(p1 != null && p2 != null && p1 != p2) { p1 = p1.father; p2 = p2.father; } if(p1 == null || p2 == null) { System.out.println("不存在公共节点"); return null; } else { return p1; } } } public boolean findTwoNode(TreeNodeWithMoreChild root, TreeNodeWithMoreChild curNode, Stack<TreeNodeWithMoreChild> path) { if(root == curNode) { return true; } else { path.push(root); boolean found = false; if(!found) { if(root.first != null) { found = findTwoNode(root.first, curNode, path); } if(!found && root.second != null) { found = findTwoNode(root.second, curNode, path); } if(!found && root.third != null) { found = findTwoNode(root.third, curNode, path); } } if(!found) { path.pop(); } return found; } } public TreeNodeWithMoreChild getFatherNode3(LinkedList<TreeNodeWithMoreChild> left, LinkedList<TreeNodeWithMoreChild> right) { if(left == null || right == null || left.isEmpty() || right.isEmpty()) { return null; } else { int n1 = left.size(); int n2 = right.size(); int sub = 0; if(n2 > n1) { sub = n2 - n1; for(int i = 0; i < n1; i++) { if(right.get(i + sub) == left.get(i)) { return left.get(i); } } } else { sub = n1 - n2; for(int i = 0; i < n2; i++) { if(left.get(i + sub) == right.get(i)) { return right.get(i); } } } return null; } } /** * 具有多个分支的树形结构; * 1.找路径; * 2.用单链表的公共节点找出父节点; * @param node1 * @param node2 * @param root * @return */
public TreeNodeWithMoreChild getCommonNode(TreeNodeWithMoreChild node1, TreeNodeWithMoreChild node2, TreeNodeWithMoreChild root) { if(root == null || node1 == null || node2 == null) { return null; } else { Stack<TreeNodeWithMoreChild> stack1 = new Stack<TreeNodeWithMoreChild>(); Stack<TreeNodeWithMoreChild> stack2 = new Stack<TreeNodeWithMoreChild>(); findTwoNode(root, node1, stack1); findTwoNode(root, node2, stack2); LinkedList<TreeNodeWithMoreChild> reversePath1 = new LinkedList<TreeNodeWithMoreChild>(); LinkedList<TreeNodeWithMoreChild> reversePath2 = new LinkedList<TreeNodeWithMoreChild>(); while(!stack1.isEmpty()) { reversePath1.offer(stack1.pop()); } while(!stack2.isEmpty()) { reversePath2.offer(stack2.pop()); } ///此处要写getFatherNode2(reversePath1, reversePath2); //因为与上面的getFatherNode2一致就不写了,但注意类型TreeNodeWithFather,此处是TreeNodeWithMoreChild; return getFatherNode3(reversePath1, reversePath2); } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TreeNode root = new TreeNode(13); TreeNode tn1 = new TreeNode(11); TreeNode tn2 = new TreeNode(14); TreeNode tn3 = new TreeNode(10); TreeNode tn4 = new TreeNode(12); root.left = tn1; root.right = tn2; tn1.left = tn3; tn1.right = tn4; FatherNodeForTree50 fnt = new FatherNodeForTree50(); TreeNode res = fnt.getFatherNode(tn4, tn2, root); System.out.println(res.val); TreeNodeWithFather rootl = new TreeNodeWithFather(5); TreeNodeWithFather left1 = new TreeNodeWithFather(15); TreeNodeWithFather left2 = new TreeNodeWithFather(25); TreeNodeWithFather left3 = new TreeNodeWithFather(35); TreeNodeWithFather rootr = new TreeNodeWithFather(54); TreeNodeWithFather right1 = new TreeNodeWithFather(55); left3.father = left2; left2.father = left1; left1.father = rootl; right1.father = rootr; rootr.father = rootl; TreeNodeWithFather r = fnt.getFatherNode2(left3, right1); System.out.println(r.val); TreeNodeWithMoreChild tn = new TreeNodeWithMoreChild(0); TreeNodeWithMoreChild tn11 = new TreeNodeWithMoreChild(1); TreeNodeWithMoreChild tn21 = new TreeNodeWithMoreChild(11); TreeNodeWithMoreChild tn31 = new TreeNodeWithMoreChild(12); TreeNodeWithMoreChild tn41 = new TreeNodeWithMoreChild(111); TreeNodeWithMoreChild tn5 = new TreeNodeWithMoreChild(112); TreeNodeWithMoreChild tn6 = new TreeNodeWithMoreChild(121); TreeNodeWithMoreChild tn7 = new TreeNodeWithMoreChild(1211); tn.first = tn11; tn11.first = tn21; tn11.second = tn31; tn21.first = tn41; tn21.second = tn5; tn31.first = tn6; tn6.first = tn7; TreeNodeWithMoreChild resss = fnt.getCommonNode(tn41, tn5, tn); System.out.println(resss.val); } }