剑指offer-第七章面试案例2(树中两个节点的公共祖先节点)

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;



//树中两个节点的最低公共祖先
//第一种情况:只是一颗二叉树,而且还是排序二叉树。思路:从根节点开始找起,如果这两个数一个大于
//根节点,一个小于根节点,那么最低公共子节点就是根节点。
//第二种情况:只是一颗普通的树,但是有指向父节点的指针。
//那么就变成 了两个链表求第一个公共节点的情况。
//第三种情况:只是一个普通的树,而且没有指针指向根节点。那么就只能用栈来存放遍历了的节点。找到相同的节点为止。
public class TreeLastCommonParent {
   public class BiTreeNode{
       int m_nValue;
       BiTreeNode m_pLeft;
       BiTreeNode m_pRight;
       BiTreeNode m_pParent;
   }
   public BiTreeNode createBiTree(int[] pre,int start,int[] ord,int end,int length){
        if(pre.length!=ord.length||pre==null||ord==null||length<=0)
            return null;
        int value=pre[start];
        BiTreeNode root=new BiTreeNode();
        root.m_nValue=value;
        root.m_pRight=root.m_pLeft=null;
        if(length==1){
            if(pre[start]==ord[end])
                return root;
            else
                throw new RuntimeException("inVaild put");
        }
        //遍历中序遍历的序列找到根节点
        int i=0;
        while(i<length){
            if(ord[end-i]==value)
                break;
            i++;
        }
        int right=i;
        int left=length-i-1;
        if(left>0)
            root.m_pLeft=createBiTree(pre,start+1,ord,end-i-1,length-i-1);
        if(right>0)
            root.m_pRight=createBiTree(pre,start+length-i,ord,end,i);
        return root;
        }
   //该树是二叉树,而且还是排序二叉树。
   public BiTreeNode commonParent1(BiTreeNode pHead,BiTreeNode p1,BiTreeNode p2){
       if(pHead==null)
           return null;
       if(p1.m_nValue<pHead.m_nValue&&p2.m_nValue>pHead.m_nValue
               ||p2.m_nValue<pHead.m_nValue&&p1.m_nValue>pHead.m_nValue){
           return pHead;
           
       }
       else if(p1.m_nValue<pHead.m_nValue&&p2.m_nValue<pHead.m_nValue){
           return commonParent1(pHead.m_pLeft,p1,p2);
           
       }
       else
           return commonParent1(pHead.m_pRight,p1,p2);
   }
   //该树有指向父节点的指针
   public BiTreeNode commonParent2(BiTreeNode pHead,BiTreeNode p1,BiTreeNode p2){
       if(pHead==null)
           return null;
       int len1=0;
       int len2=0;
       while(p1!=pHead){
           len1++;
           p1=p1.m_pParent;
       }
       while(p2!=pHead){
           len2++;
           p2=p2.m_pParent;
       }
       int dif=len1-len2;
       BiTreeNode longest=p1;
       BiTreeNode shortest=p2;
       if(dif<0){
           dif=len2-len1;
           longest=p2;
           shortest=p1;
       }
       for(int i=0;i<dif;i++)
           longest=longest.m_pParent;
       while(longest!=shortest){
           longest=longest.m_pParent;
           shortest=shortest.m_pParent;
       }
       return longest;
   }
   //该树没有指向父节点的指针
   public BiTreeNode commonParent3(BiTreeNode pHead,BiTreeNode p1,BiTreeNode p2){


       if(pHead==null)
           return null;
       Queue<BiTreeNode> path1=new LinkedList<BiTreeNode>();
       Queue<BiTreeNode> path2=new LinkedList<BiTreeNode>();
       Queue<BiTreeNode> longPath=path1;
       Queue<BiTreeNode> shortPath=path2;
       BiTreeNode head=pHead;
       getNodePath(pHead,p1,path1);
       pHead=head;
       getNodePath(pHead,p2,path2);
       int dif=path1.size()-path2.size();
      
       if(dif<0){
           dif=path2.size()-path1.size();
           longPath=path2;
           shortPath=path1;
       }
       for(int i=0;i<dif;i++){
           longPath.remove();
       }
       while(longPath.peek()!=shortPath.peek())
       {
           longPath.remove();
           shortPath.remove();
       }
       
       
    
       return longPath.peek();
      
     }
   
   public boolean getNodePath(BiTreeNode pHead,BiTreeNode p,Queue<BiTreeNode> path1){
       if(pHead==null)
           return false;
       
       if(pHead==p||getNodePath(pHead.m_pLeft,p,path1)||
       getNodePath(pHead.m_pRight,p,path1)){
           path1.add(pHead);
           return true;
       }
       return false;
        
     
      }
       
   
   public static void main(String[] args){
       int[] pre={8,4,3,7,9};
       int[] ord={3,4,7,8,9};
       TreeLastCommonParent treeLastCommon=new TreeLastCommonParent();
       BiTreeNode pHead=treeLastCommon.createBiTree(pre,0,ord,pre.length-1,pre.length);
       BiTreeNode p1=pHead.m_pLeft.m_pRight;
       BiTreeNode p2=pHead.m_pLeft.m_pLeft;
       BiTreeNode pCommon=treeLastCommon.commonParent1(pHead, p1, p2);
       BiTreeNode pCommon3= treeLastCommon.commonParent3(pHead, p1, p2);
       System.out.println(pCommon.m_nValue+" ");
       System.out.println(pCommon3.m_nValue+" ");
   }
}

 

posted @ 2015-09-03 11:25  lisahappy  阅读(310)  评论(0编辑  收藏  举报