本文參考了
問題1:如何判斷單鏈表有環
2:如果有環,在**有環的開始點
3 判斷兩個鍊錶是否相交
問題一:
設定兩個指標(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。(當然,fast先行頭到尾部為null,則為無環鏈表)程式如下:loop_2
問題二:
二、找到環的入口點
當fast若與slow相遇時,slow肯定沒有走遍歷完鍊錶,而fast已經在環內迴圈了n圈(1<=n)。假設slow走了s步,則fast走了2s步(fast步數還等於s 加上在環上多轉的n圈),設環長為r,則:
2s = s + nr
s= nr
設整個鍊錶長l,入口環與相遇點距離為x,起點到環入口點的距離為a。
a + x = nr
a + x = (n – 1)r +r = (n-1)r + l - a
a = (n-1)r + (l – a – x)
(l – a – x)為相遇點到環入口點的距離,由此可知,從煉表頭到環入口點等於(n-1)迴圈內環+相遇點到環入口點,於是我們從煉表頭、與相遇點分別設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。在函式的 loop_2
問題三:如果2個鍊錶相交,可以判斷最後元素相交否,如相交一定,相等;否則不等。程式如loop()。還可以把鏈head_1的尾和head_2的頭相連,通過判斷是否有環,來判斷是否相交,找到環的入口點,找到2個鏈的交點 **如 loop2
// 最短摘要的生成.cpp : 定義控制台應用程式的入口點。
///*author:songzhengchao
time:2013/11/6*/
#include "stdafx.h"
#include #include using namespace std;
/*define the data struct for link */
typedef struct node
node;
/*construct the link head_1 1-->2-->6-->7-->8
head_2 3-->4-->6-->7-->8
*/void make(node * &head_1,node * &head_2)
node *pre_2=head_2;
node *q;
for(i=3;i<=4;i++)
node *pre=new node ;
for(i=6;i<=8;i++)
else
}}/*列印元素*/
void print(node *head)
cout<<"---end---"while(q->next)
if(q==p)
node *q=head_2;
p->next=q;
int flag=0;//判斷是否有環的標誌
node *fast,*slow;
fast=slow=head_1;
while(fast->next) }
/*下面求交點,即環的開始點*/
if(flag)
cout<<"相遇的節點為---->"head_2->next=null;
make(head_1,head_2);
print(head_2);
loop(head_1,head_2);
loop_2(head_1,head_2);
return 0;
}
判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解
摘要 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?擴充套件 判斷兩個單鏈表是否相交,如果相交,給出相交的第乙個點。有乙個單鏈表,其中可能有乙個環,也就是某...
判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解
有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...
判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解
有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...