1. 程式人生 > >求兩個單鏈表交點and判斷連結串列是否有環

求兩個單鏈表交點and判斷連結串列是否有環

求單鏈表交點演算法

先求得兩條連結串列各自的長度,如果最後一個節點的地址相同,則確定連結串列有交點。然後求出長度差值k,讓長的連結串列指標先走k步,然後兩個連結串列指標同時走,邊走邊比較,第一次相等處即是交點。

程式碼:

struct Node  
{  
    int data;  
    struct Node * next;  
};  
  
 Node* FixIntersetion(Node* pHead1, Node* pHead2)  
{  
    Node* p1 = pHead1;  
    Node* p2 = pHead2;  
    int i = 1, j = 1, k = 0, diff = 0;  
    //如果都是空連結串列,肯定沒有交點  
    if(pHead2 == NULL || pHead2 == NULL)  
    {  
        return NULL;  
    }  
    //獲取連結串列長度  
    while(p1->next != NULL)  
    {  
        p1 = p1->next;  
        i++;  
    }  
    while(p2->next != NULL)  
    {  
        p2 = p2->next;  
        j++;  
    }  
    //開始判斷是否存在交點  
    if(p1 != p2)  
    {//根據有交點時,兩個連結串列在交點及其之後的部分是公共的,因此,有交點的單鏈表的尾節點必定相同  
        return NULL;        //如果尾節點不同,直接返回NULL  
    }  
    else                   //否則尋找第一個相同的節點  
    {  
        p1=pHead1;  
        p2=pHead2;  
        //使得兩者的起始比較位置離尾部的長度一致  
        if(i>j)  
        {  
            diff=i-j;   
            for(k=0; k<diff; k++)  
            {  
                p1 = p1->next;  
            }  
        }  
        if(i<j)  
        {  
            diff=j-i;   
            for(k=0; k<diff; k++)  
            {  
                p2 = p2->next;  
            }  
        }  
        //開始比對,得出交點  
        while(p1 != p2)  
        {  
            p1 = p1->next;  
            p2 = p2->next;  
        }  
        return p1;  
    }  
}  

判斷連結串列是否有環演算法

兩個指標一快一慢,快指標一次走兩步,慢指標一次走一步,如果快指標首先走到頭則無環。如果快慢指標會相等,則有環。

程式碼

bool FixRing(Node * pHead)  
{  
    Node * pSlow = pHead ;  
    Node * pFast = pHead;  
  
    while ( pFast && pFast -> next )  //如果存在環,不存在p-next=NULL的情況  
    {  
        pSlow = pSlow -> next;//前進一步  
        pFast = pFast -> next -> next;//前進兩步  
        if ( pSlow == pFast )   
            break ;  
    }  
    return   ! (pFast == NULL || pFast -> next == NULL);  
}