通过5个解决方案教你C++中检测链表中的循环,快来看看,是否对你有帮助!
给定一个链表,检查链表是否有循环。下图显示了带有循环的链表。
以下是执行此操作的不同方法
解决方案1:散列方法
遍历该列表,并将节点地址始终放在哈希表中。在任何时候,如果达到NULL,则返回false,如果当前节点的下一个指向Hash中先前存储的任何节点,则返回true。
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
};
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node = new Node;
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
bool detectLoop(struct Node* h)
{
unordered_set<Node*> s;
while (h != NULL) {
if (s.find(h) != s.end())
return true;
s.insert(h);
h = h->next;
}
return false;
}
int main()
{
struct Node* head = NULL;
push(&head, 20);
push(&head, 4);
push(&head, 15);
push(&head, 10);
head->next->next->next->next = head;
if (detectLoop(head))
cout << "Loop found";
else
cout << "No Loop";
return 0;
}
复杂度分析:
时间复杂度:O(n)。
只需循环一次即可。
辅助空间:O(n)。
n是将值存储在哈希图中所需的空间。
解决方案2:通过修改链表数据结构,无需哈希图即可解决此问题。
方法:此解决方案需要修改基本链表数据结构。
每个节点都有一个访问标志。
遍历链接列表并继续标记访问的节点。
如果您再次看到一个访问过的节点,那么就会有一个循环。该解决方案适用于O(n),但每个节点都需要其他信息。
此