求二叉樹中兩個節點的最小公共祖先(LCA)
阿新 • • 發佈:2019-02-16
題目要求:求二叉樹中兩個節點p,q的最低公共祖先節點
首先,題目中沒有明確說明節點的結構,所以思考了一會然後問面試官節點有沒有父指標,面試官說有沒有父指標有影響嗎?我說有,然後他笑著說你來說說看。當時,只做出來有父指標的情況,沒有父指標的情況壓根想不出來。後來會實驗室靜下心來很快就想到了思路。這裡分這兩種情況討論:
1. 二叉樹節點具有父指標
在節點具有父指標的情況下,顯然此二叉樹就可以看成是通過父指標連線的"T"型連結串列,題目也就轉化成查詢"T"型連結串列的第一個公共節點。(可看做兩個連結串列相交,求連結串列相交的第一個公共節點)假設p,q分別為所求的兩個節點,則通過遍歷一遍可以知道p,q分別到根節點的長度pLen和qLen。這樣就知道pLen和qLen之間長度之差,也就知道p、q到它們的第一個公共祖先節點k長度之差L。因為p,q到根節點的路徑中都包含k到根節點的路徑,所以pLen和qLen之差等於p、q到k的長度之差。然後,讓p、q到根節點路徑長度大的先向前走L,然後長度小再和大的同時向前遍歷,當它們兩指向同一個節點時,則那個節點即是所求。
- /**
- * 有父指標情況下,查詢兩個節點的最低公共節點
- * @author chosen0ne
- * 2011-01-18
- */
- class BTree<T>{
- private BTNode<T> root;
- public BTree(BTNode<T> r){
- this.root=r;
- }
- /**
- * 查詢兩個節點的最低公共祖先節點
- * @param p
- * @param q
-
* @return BTNode<T> 最低公共祖先節點,沒有找到返回null
- */
- public BTNode<T> findLowestAncestor(BTNode<T> p,BTNode<T> q){
- if(p==null||q==null)
- thrownew NullPointerException();
- int pLen=0,qLen=0;//p,q兩個節點到根節點的路徑長度
- //計算p到根節點的長度
-
for(BTNode<T> ancestor=p.parent;ancestor!=null
- pLen++;
- //計算q到根節點的長度
- for(BTNode<T> ancestor=q.parent;ancestor!=null;ancestor=ancestor.parent)
- qLen++;
- //如果p到根節點的長度比q長,則讓p前進pLen-qLen
- for(;pLen>qLen;pLen--)
- p=p.parent;
- //如果q到根節點的長度比p長,則讓q前進qLen-pLen
- for(;qLen>pLen;qLen--)
- q=q.parent;
- //此時,p和q到根節點的長度相同。假設k是最近的公共節點,則p和q到k的長度相同
- //p和q按照相同步長1向前遍歷,如果存在公共節點則p和去會同時指向它
- while(q!=null&&p!=null&&p!=q){
- q=q.parent;
- p=p.parent;
- }
- if(p==q)
- return p;
- returnnull;
- }
- /**
- * 測試方法,在t中查詢a,b的最低公共祖先節點
- * @param t
- * @param a
- * @param b
- */
- privatestatic<T> void test(BTree<T> t, BTNode<T> a, BTNode<T> b){
- BTree.BTNode<T> p=t.findLowestAncestor(b,a);
- if(p!=null)
- System.out.println(a.data+","+b.data+"的最低公共祖先節點是 :"+p.data);
- else
- System.out.println(a.data+","+b.data+"沒有公共祖先節點");
- }
- publicstaticvoid main(String[] arg){
- /* 構造如下二叉樹
- a
- / /
- b c
- / / / /
- d e f g
- */
- BTree.BTNode<String> g=new BTree.BTNode().data("g");
- BTree.BTNode<String> f=new BTree.BTNode().data("f");
- BTree.BTNode<String> e=new BTree.BTNode().data("e");
- BTree.BTNode<String> d=new BTree.BTNode().data("d");
- BTree.BTNode<String> c=new BTree.BTNode().data("c").left(f).right(g);
- f.parent(c);
- g.parent(c);
- BTree.BTNode<String> b=new BTree.BTNode().data("b").left(d).right(e);
- d.parent(b);
- e.parent(b);
- BTree.BTNode<String> a=new BTree.BTNode().data("a").left(b).right(c);
- b.parent(a);
- c.parent(a);
- BTree<String> t=new BTree<String>(a);
- test(t,c,f);
- }
- staticclass BTNode<T>
- {
- BTNode<T> left;
- BTNode<T> right;
- BTNode<T> parent;
- T data;
- public BTNode(){}
- public BTNode(BTNode<T> l,BTNode<T> r,BTNode<T> p,T d){
- this.left=l;
- this.right=r;
- this.parent=p;
- this.data=d;
- }
- BTNode<T> left(BTNode<T> l){
- this.left=l;
- returnthis;
- }
- BTNode<T> right(BTNode<T> r){
- this.right=r;
- returnthis;
- }
- BTNode<T> parent(BTNode<T> p){
- this.parent=p;
- returnthis;
- }
- BTNode<T> data(T d){
- this.data=d;
- returnthis;