日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
五個解決辦法教你C++中檢測鏈表中的循環(huán)

給定一個鏈表,檢查鏈表是否有循環(huán)。下圖顯示了帶有循環(huán)的鏈表。

專注于為中小企業(yè)提供網(wǎng)站建設(shè)、網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)寧德免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

以下是執(zhí)行此操作的不同方法 

解決方案1:散列方法:

遍歷該列表,并將節(jié)點(diǎn)地址始終放在哈希表中。在任何時候,如果達(dá)到NULL,則返回false,如果當(dāng)前節(jié)點(diǎn)的下一個指向Hash中先前存儲的任何節(jié)點(diǎn),則返回true。

 
 
 
  1. #include  
  2. using namespace std; 
  3. struct Node { 
  4.     int data; 
  5.     struct Node* next; 
  6. }; 
  7.   
  8. void push(struct Node** head_ref, int new_data) 
  9.     struct Node* new_node = new Node; 
  10.     new_node->data = new_data; 
  11.     new_node->next = (*head_ref); 
  12.     (*head_ref) = new_node; 
  13. bool detectLoop(struct Node* h) 
  14.     unordered_set s; 
  15.     while (h != NULL) { 
  16.         if (s.find(h) != s.end()) 
  17.             return true; 
  18.         s.insert(h); 
  19.   
  20.         h = h->next; 
  21.     } 
  22.   
  23.     return false; 
  24. int main() 
  25.     struct Node* head = NULL; 
  26.   
  27.     push(&head, 20); 
  28.     push(&head, 4); 
  29.     push(&head, 15); 
  30.     push(&head, 10); 
  31.     head->next->next->next->next = head; 
  32.   
  33.     if (detectLoop(head)) 
  34.         cout << "Loop found"; 
  35.     else 
  36.         cout << "No Loop"; 
  37.   
  38.     return 0; 

復(fù)雜度分析:

時間復(fù)雜度: O(n)。
只需循環(huán)一次即可。

輔助空間: O(n)。
n是將值存儲在哈希圖中所需的空間。

解決方案2:通過修改鏈表數(shù)據(jù)結(jié)構(gòu),無需哈希圖即可解決此問題。
方法:此解決方案需要修改基本鏈表數(shù)據(jù)結(jié)構(gòu)。

  • 每個節(jié)點(diǎn)都有一個訪問標(biāo)志。
  • 遍歷鏈接列表并繼續(xù)標(biāo)記訪問的節(jié)點(diǎn)。
  • 如果您再次看到一個訪問過的節(jié)點(diǎn),那么就會有一個循環(huán)。該解決方案適用于O(n),但每個節(jié)點(diǎn)都需要其他信息。
  • 此解決方案的一種變體不需要修改基本數(shù)據(jù)結(jié)構(gòu),可以使用哈希來實現(xiàn),只需將訪問的節(jié)點(diǎn)的地址存儲在哈希中,如果您看到哈希中已經(jīng)存在的地址,則存在一個循環(huán)。

C++:

 
 
 
  1. #include  
  2. using namespace std; 
  3. struct Node { 
  4.     int data; 
  5.     struct Node* next; 
  6.     int flag; 
  7. }; 
  8.   
  9. void push(struct Node** head_ref, int new_data) 
  10.     struct Node* new_node = new Node; 
  11.     new_node->data = new_data; 
  12.   
  13.     new_node->flag = 0; 
  14.     new_node->next = (*head_ref); 
  15.     (*head_ref) = new_node; 
  16. bool detectLoop(struct Node* h) 
  17.     while (h != NULL) { 
  18.         if (h->flag == 1) 
  19.             return true; 
  20.         h->flag = 1; 
  21.   
  22.         h = h->next; 
  23.     } 
  24.   
  25.     return false; 
  26. int main() 
  27.     struct Node* head = NULL; 
  28.   
  29.     push(&head, 20); 
  30.     push(&head, 4); 
  31.     push(&head, 15); 
  32.     push(&head, 10); 
  33.     head->next->next->next->next = head; 
  34.   
  35.     if (detectLoop(head)) 
  36.         cout << "Loop found"; 
  37.     else 
  38.         cout << "No Loop"; 
  39.   
  40.     return 0; 

復(fù)雜度分析:

時間復(fù)雜度: O(n)。
只需循環(huán)一次即可。

輔助空間: O(1)。
不需要額外的空間。

解決方案3:Floyd的循環(huán)查找算法
方法:這是最快的方法,下面進(jìn)行了介紹:

  • 使用兩個指針遍歷鏈表。
  • 將一個指針(slow_p)移動一個,將另一個指針(fast_p)移動兩個。
  • 如果這些指針在同一節(jié)點(diǎn)相遇,則存在循環(huán)。如果指針不符合要求,則鏈接列表沒有循環(huán)。

Floyd的循環(huán)查找算法的實現(xiàn):

 
 
 
  1. #include  
  2. using namespace std; 
  3. class Node { 
  4. public: 
  5.     int data; 
  6.     Node* next; 
  7. }; 
  8.   
  9. void push(Node** head_ref, int new_data) 
  10.     Node* new_node = new Node(); 
  11.     new_node->data = new_data; 
  12.     new_node->next = (*head_ref); 
  13.     (*head_ref) = new_node; 
  14.   
  15. int detectLoop(Node* list) 
  16.     Node *slow_p = list, *fast_p = list; 
  17.   
  18.     while (slow_p && fast_p && fast_p->next) { 
  19.         slow_p = slow_p->next; 
  20.         fast_p = fast_p->next->next; 
  21.         if (slow_p == fast_p) { 
  22.             return 1; 
  23.         } 
  24.     } 
  25.     return 0; 
  26. int main() 
  27.     Node* head = NULL; 
  28.   
  29.     push(&head, 20); 
  30.     push(&head, 4); 
  31.     push(&head, 15); 
  32.     push(&head, 10); 
  33.     head->next->next->next->next = head; 
  34.     if (detectLoop(head)) 
  35.         cout << "Loop found"; 
  36.     else 
  37.         cout << "No Loop"; 
  38.     return 0; 

解決方案4:在不修改鏈接列表數(shù)據(jù)結(jié)構(gòu)的情況下標(biāo)記訪問的節(jié)點(diǎn)
在此方法中,將創(chuàng)建一個臨時節(jié)點(diǎn)。使遍歷的每個節(jié)點(diǎn)的下一個指針指向該臨時節(jié)點(diǎn)。這樣,我們將節(jié)點(diǎn)的下一個指針用作標(biāo)志來指示該節(jié)點(diǎn)是否已遍歷。檢查每個節(jié)點(diǎn)以查看下一個節(jié)點(diǎn)是否指向臨時節(jié)點(diǎn)。在循環(huán)的第一個節(jié)點(diǎn)的情況下,第二次遍歷該條件將成立,因此我們發(fā)現(xiàn)該循環(huán)存在。如果遇到一個指向null的節(jié)點(diǎn),則循環(huán)不存在。
下面是上述方法的實現(xiàn):

 
 
 
  1. #include  
  2. using namespace std; 
  3.   
  4. struct Node { 
  5.     int key; 
  6.     struct Node* next; 
  7. }; 
  8.   
  9. Node* newNode(int key) 
  10.     Node* temp = new Node; 
  11.     temp->key = key; 
  12.     temp->next = NULL; 
  13.     return temp; 
  14. void printList(Node* head) 
  15.     while (head != NULL) { 
  16.         cout << head->key << " "; 
  17.         head = head->next; 
  18.     } 
  19.     cout << endl; 
  20. bool detectLoop(Node* head) 
  21.     Node* temp = new Node; 
  22.     while (head != NULL) { 
  23.         if (head->next == NULL) { 
  24.             return false; 
  25.         } 
  26.         if (head->next == temp) { 
  27.             return true; 
  28.         } 
  29.         Node* nex = head->next; 
  30.         head->next = temp; 
  31.         head = nex; 
  32.     } 
  33.   
  34.     return false; 
  35. int main() 
  36.     Node* head = newNode(1); 
  37.     head->next = newNode(2); 
  38.     head->next->next = newNode(3); 
  39.     head->next->next->next = newNode(4); 
  40.     head->next->next->next->next = newNode(5); 
  41.     head->next->next->next->next->next = head->next->next; 
  42.   
  43.     bool found = detectLoop(head); 
  44.     if (found) 
  45.         cout << "Loop Found"; 
  46.     else 
  47.         cout << "No Loop"; 
  48.   
  49.     return 0; 

復(fù)雜度分析:

時間復(fù)雜度: O(n)。
只需循環(huán)一次即可。

輔助空間: O(1)。
不需要空間。

解決方案5:存放長度

在此方法中,將創(chuàng)建兩個指針,第一個(始終指向頭)和最后一個指針。每次最后一個指針移動時,我們都會計算第一個和最后一個之間的節(jié)點(diǎn)數(shù),并檢查當(dāng)前節(jié)點(diǎn)數(shù)是否大于先前的節(jié)點(diǎn)數(shù),如果是,我們通過移動最后一個指針進(jìn)行操作,否則就意味著我們已經(jīng)到達(dá)循環(huán)的終點(diǎn),因此我們相應(yīng)地返回輸出。

 
 
 
  1. #include  
  2. using namespace std; 
  3.   
  4. struct Node { 
  5.     int key; 
  6.     struct Node* next; 
  7. }; 
  8.   
  9. Node* newNode(int key) 
  10.     Node* temp = new Node; 
  11.     temp->key = key; 
  12.     temp->next = NULL; 
  13.     return temp; 
  14. void printList(Node* head) 
  15.     while (head != NULL) { 
  16.         cout << head->key << " "; 
  17.         head = head->next; 
  18.     } 
  19.     cout << endl; 
  20. int distance(Node* first, Node* last) 
  21.     int counter = 0; 
  22.   
  23.     Node* curr; 
  24.     curr = first; 
  25.   
  26.     while (curr != last) { 
  27.         counter += 1; 
  28.         curr = curr->next; 
  29.     } 
  30.   
  31.     return counter + 1; 
  32. bool detectLoop(Node* head) 
  33.     Node* temp = new Node; 
  34.   
  35.     Node *first, *last; 
  36.     first = head; 
  37.     last = head; 
  38.     int current_length = 0; 
  39.     int prev_length = -1; 
  40.   
  41.     while (current_length > prev_length && last != NULL) { 
  42.           prev_length = current_length; 
  43.         current_length = distance(first, last); 
  44.         last = last->next; 
  45.     } 
  46.       
  47.     if (last == NULL) { 
  48.         return false; 
  49.     } 
  50.     else {  
  51.         return true; 
  52.     } 
  53. int main() 
  54.     Node* head = newNode(1); 
  55.     head->next = newNode(2); 
  56.     head->next->next = newNode(3); 
  57.     head->next->next->next = newNode(4); 
  58.     head->next->next->next->next = newNode(5); 
  59.     head->next->next->next->next->next = head->next->next; 
  60.   
  61.     bool found = detectLoop(head); 
  62.     if (found) 
  63.         cout << "Loop Found"; 
  64.     else 
  65.         cout << "No Loop Found"; 
  66.   
  67.     return 0; 

}


網(wǎng)站名稱:五個解決辦法教你C++中檢測鏈表中的循環(huán)
分享地址:http://m.5511xx.com/article/dpdoepe.html