如何判斷一個單鏈表是否有環

題目要求:給定一個單鏈表的頭指針head,要求寫一個函數判斷這個單鏈表是否是一個有環單鏈表。

單鏈表中的節點定義如下:

struct listNode
{
int val;
struct listNode *next;
};

方法1:首先定義一個map<listNode *, int> map,然後從單鏈表的頭指針開始往後遍歷,每次遇到一個指針p,就判斷map[pCur]是否爲0,若爲0,則將map[pCur]賦值爲1,表示該節點是頭一次訪問;如果map[pCur]的值爲2,則說明這個節點已經被訪問過一次了,說明這個單鏈表中是存在一個環的。


方法2:定義兩個指針fast和slow,slow初始值爲head,fast的初始值爲head->next,fast每次前進2步,slow每次前進1步,兩個指針是同時向後移動的,當快慢指針相遇了,表示單鏈表中是有環的,否則的話就表示單鏈表無環。

代碼如下:

#include <iostream>
#include <vector>
#include <map>
using namespace std;


struct listNode
{
int val;
struct listNode *next;
};


// 方法1
listNode *isLoop1(listNode *head)
{
if(head == NULL)
{
return NULL;
}
listNode *pCur = head;
map<listNode *, int> map;
while(pCur != NULL)
{
if (map[pCur] == 0)
{
map[pCur] = 1;
}
else if(map[pCur] == 1)
{
return pCur;
}
pCur = pCur->next;
}
}
// 方法2
listNode *isLoop2(listNode *head)
{
listNode *slow = head;
listNode *fast = head->next;
// 鏈表長爲2時,判斷是否有環
if (fast == NULL || fast == slow)
{
return NULL;
}
while (fast != NULL)
{
if (fast == slow)
{
return fast;
}
// fast每次前進2步
fast = fast->next;
fast = fast->next;
// slow每次前進1步
slow = slow->next;
}
return NULL;
}


int main()
{
// 先建立一個有11個節點的單鏈表:0-1-2-3-4-5-6-7-8-9-10
listNode *head = new listNode;
head->val = 0;
int n = 0;
listNode *cur = head;
while(++n <= 10)
{
cur->next = new listNode;
cur = cur->next;
cur->val = n;
}
listNode *tail = cur;
cur = head;
n = 0;
while(++n <= 5)
{
cur = cur->next;
}
// 將單鏈表的環入口定義爲節點值爲5的節點
tail->next = cur;
// 調用方法1的函數isLoop1尋找環入口
listNode *result = isLoop1(head);
cout << "單鏈表的環入口值爲:" << result->val << endl;


// 調用方法2的函數isLoop2尋找環入口
result = isLoop1(head);
cout << "單鏈表的環入口值爲:" << result->val << endl;




return 0;
}


程序運行如下圖所示:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章