1. 程式人生 > >判斷單鏈表是否有環,如果有找出環的入口位置=>求兩個相交連結串列的交點

判斷單鏈表是否有環,如果有找出環的入口位置=>求兩個相交連結串列的交點

首先如何判斷一個連結串列是否有環:

設定兩個指標(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步,如果連結串列存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。(當然,fast先行頭到尾部為NULL,則為無環連結串列)程式如下:

bool IsExitsLoop(slist *head)
{

slist *slow = head, *fast = head;

while ( fast && fast->next )
{
slow = slow->next;
fast = fast->next->next;
if ( slow == fast )

break;
}

return !(fast == NULL || fast->next == NULL);
}

下面看如何找這個環的入口:

第一種方法:fast若與slow相遇時slow肯定沒有走遍歷完連結串列(這是因為如果這個連結串列整個是個環的話,當slow恰好到達連結串列終點的時候fast正好追上slow,當這個環不是整個連結串列的時候,則肯定在slow到達終點的時候就被fast追上了),而fast已經在環內迴圈了n(1<=n)。假設slow走了s步,則fast走了2s步(fast步數還等於s加上在環上多轉的n圈),設環長為r,則:因為2s = s + nr
所以得出s= nr

設整個連結串列長L環入口與相遇點距離為x,起點到環入口點的距離為a則有a + x = s 推出 a = nr分解有a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)
(L – a – x)
相遇點到環入口點的距離,由此可知,從連結串列頭到環入口點等於(n-1)迴圈內環+相遇點到環入口點,於是我們從連結串列頭、與相遇點分別設一個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。程式描述如下:

slist* FindLoopPort(slist *head)
{
slist *slow = head, *fast = head;

while ( fast && fast->next )
{
slow = slow->next;
fast = fast->next->next;
if ( slow == fast ) break;
}
if (fast == NULL || fast->next == NULL)
return NULL;
slow = head;
while (slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}

還有一種方法就是使用一個指標,每次遍歷一個的時候把這個節點的地址存到一個vector,下一個遍歷的時候從vector中查詢看是否存在,如果在指標為NULL之前,出現了在vector中的節點,則說明有環存在。

下面看如何從兩個相交連結串列找出相交點,其實這是連結串列環的一個衍生問題

一、將其中一個連結串列首尾相連,檢測另外一個連結串列是否存在環,如果存在,則兩個連結串列相交,而檢測出來的依賴環入口即為相交的第一個點。二、如果兩個連結串列相交,那個兩個連結串列從相交點到連結串列結束都是相同的節點,我們可以先遍歷一個連結串列,直到尾部,再遍歷另外一個連結串列,如果也可以走到同樣的結尾點,則兩個連結串列相交。這時我們記下兩個連結串列length,再遍歷一次,長連結串列節點先出發前進(lengthMax-lengthMin)步,之後兩個連結串列同時前進,每次一步,相遇的第一點即為兩個連結串列相交的第一個點。

相關推薦

判斷單鏈是否如果入口位置=>相交連結串列交點

首先如何判斷一個連結串列是否有環: 設定兩個指標(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步,如果連結串列存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。(當然,fast先行頭到尾部為NULL,則為無環連結串列

筆試題:判斷一個單鏈是否如果的起始位置

</pre><pre name="code" class="cpp">Node * FindLoop(Node *phead) { Node *p = phead,q = phead,h = phead; while(p && q->next)

判斷連結串列是否如果返回入的第一節點。

如何判斷連結串列有環,這個問題很簡單,有環的連結串列,在遍歷的時候會永遠在環裡轉下去。 但如何返回入環的第一個節點,當然最簡單的思路是用額外的空間記錄是否訪問過該節點,如果訪問過,就立刻停止遍歷,並返回。 在《程式設計師程式碼面試指南》中,作者採用了兩個指標

用java實現實時監控中的資料如果新新增的資料就通知外部伺服器查詢這條新增的資料。

使用java的定時器吧 首先建立一個Servlet監聽器,(伺服器一啟動監聽器就執行的) 在監聽器中建立一個定時器(這才是最重要的) 建立一條簡訊傳送執行緒(主要用來發送簡訊) 定時器每5秒查一次資料庫(這個時間可以自己定義,當然也可以直接用執行緒+死迴圈

排序單鏈、 並有序連結串列, 合併後依然有序

建立連結串列節點結構 <span style="font-family:Microsoft YaHei;">typedef struct strNode { struct strNo

資料結構-線性- 01 “有序連結串列序列的合併” 問題

題目要求: 本題要求實現一個函式,將兩個連結串列表示的遞增整數序列合併為一個非遞減的整數序列。 函式介面定義: List Merge( List L1, List L2 ); 其中List結構定義如下: typedef struct Node *PtrToNode; struc

合併有序連結串列合併之後仍有序

合併兩個有序連結串列,合併之後仍有序。 標頭檔案引用連結串列的一些基本操作 ListNode * MergeOrderedList(ListNode *List1,ListNode *List2) { ListNode *cur1 = List1; ListNode *cur2

合併有序連結串列合併後依然有序

pNode MergeSList(pList plist1, pList plist2) { pNode pNewHead = NULL;//新連結串列 pNode pTail = NULL;//新連結串列的尾指標 pNode pL1 = plist1; pNode

合併有序連結串列合併之後任然是有序的並輸出。

合併連結串列相信大家都特別熟悉,但是如果要加上一定的輸出格式,難度就會有所增加,不說了,見程式碼。 #include<iostream> using namespace std; struct Node{ Node *next; int data

六、判斷單向連結串列是否相交

判斷兩個單向連結串列是否相交,有兩種情況,一種是兩個不帶環的單向連結串列相交,一種是兩個帶環的單向連結串列相交。 情況1:兩個不帶環的單向連結串列相交 /*判斷兩個不帶環的單向連結串列是否相交。時間

線性——有序連結串列序列的交集

已知兩個非降序連結串列序列S1與S2,設計函式構造出S1與S2的交集新連結串列S3。 輸入格式: 輸入分兩行,分別在每行給出由若干個正整數構成的非降序序列,用−1表示序列的結尾(−1不屬於這個序列)。數字用空格間隔。 輸出格式: 在一行中輸出兩個輸入序列的交集序列,數字間用空格分開,

線性——有序連結串列序列的合併

已知兩個非降序連結串列序列S1與S2,設計函式構造出S1與S2合併後的新的非降序連結串列S3。 輸入格式: 輸入分兩行,分別在每行給出由若干個正整數構成的非降序序列,用−1表示序列的結尾(−1不屬於這個序列)。數字用空格間隔。 輸出格式: 在一行中輸出合併後新的非降序連結串列,數字間

合併有序連結串列合併後依然有序 --- 三種方法

1.合併連結串列p1,p2到p1上 void CombineList(ListNode** p1,ListNode* p2)//合併連結串列p1,p2 到p1 { if (*p1 == NULL) { *p1 = p2;

Java將有序連結串列合併為一個有序連結串列、將序數組合併成一個有序陣列

有序連結串列合併 題目:已知兩個連結串列head1和head2各自有序,請把它們合併成一個連結串列依然有序。結果連結串列要包含head1和head2的所有節點,即使節點值相同。 分析:此題目使

輸入遞增連結串列合併為一個遞增連結串列(面試題)

輸入兩個遞增連結串列,合併為一個遞增連結串列。 public class LinkedTest { public static void main(String[] args) {

合併有序連結串列合併之後依舊有序

解法一   使用遞迴 struct list_node { int data; list_node* next; list_node(int data) :data(data) , n

給定單鏈檢測是否如果進入的第一節點

判斷單向連結串列是否有環,可以採用快指標與慢指標的方式來解決。即定義一個快指標fast和一個慢指標slow,使得fast每次跳躍兩個節點,slow每次跳躍一個節點。如果連結串列沒有環的話,則slow與fast永遠不會相遇(這裡連結串列至少有兩個節點);如果有環,則fast與slow將會在環中相遇。判斷出

資料結構和演算法設計專題之---判斷單鏈中是否的長度入口節點

題目: 給定一個單鏈表,只給出頭指標head: 1、如何判斷是否存在環? 2、如何知道環的長度? 3、如何找出環的連線點在哪裡? 4、帶環連結串列的長度是多少?   解法: 1、對於問題1,使用追趕的

判斷單鏈是否入口【python】

問題: 1、如何判斷一個連結串列是不是這類連結串列? 2、如果連結串列為存在環,如果找到環的入口點? 一、判斷連結串列是否存在環,辦法為: 設定兩個指標(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步,如果連結串列存在環,則fast必定先進入環,而slow後進入環

11.判斷單鏈是否

兩個指針 next 測試 重載 else reader sta clas 復雜度 判斷單鏈表是否有環: 這裏也是用到兩個指針,如果一個鏈表有環,那麽用一個指針去遍歷,是永遠走不到頭的。 因此,我們用兩個指針去遍歷:first指針每次走一步,second指針每次走兩步