判断链表是否有环
有环单链表 就是链表尾结点不指向null,而是任意一个单链表结点
思路一:利用set 遍历链表,依次将结点放入set中,第一个放入失败的就是第一个入环结点,否则没有环,但是空间复杂度为O(n)。
void hoop1( node* head) {
set<node*, cmp>s;
node *p = head;
while (p != NULL) {
node* q = p->next;
pair<set<node*, cmp>::iterator, bool> it = s.insert(p);
if (it.second == false) {
cout << "有环,第一个入环的值为" << p->data<<endl;
break;
}
p = q;
}
if (p == NULL)
cout << "无环";
}
思路二:设置两个指针 fast slow,快指针一次走两步,慢指针一次走一步,若快指针遇到null,则不存在环,否则快、慢指针必然会相遇,当相遇时让快指针从新回到链表开始位置,移动速率和慢指针一致,一次走一步,此时两指针必然会在第一个入环结点相遇。
void hoop2( node* head) {
if (head->next->next) {
node *slow ,*fast;
slow = fast = head->next;
while (fast->next != NULL && fast->next->next != NULL) {
slow = slow->next;//一次走一步
fast = fast->next->next;//一次走两步
if (fast == slow)
break; //相遇跳出循环
}
if (fast->next == NULL) {
cout << "无环" << endl;
}
else { //是因为fast == slow跳出循环 此时有环
fast = head->next;
while (fast != slow) {
slow = slow->next;//一次走一步
fast = fast->next;//一次走一步
}
cout << "有环,第一个入环的值为" << fast->data<<endl;
}
}
}
完整源代码:
#include <iostream>
#include <map>
#include <set>
using namespace std;
struct List {
int data;
struct List* next;
};
typedef List node;
struct cmp {
bool operator()(const node* n1, const node* n2)const {
if (n1->data > n2->data)
return true;
else
return false;
}
};
void hoop1( node* head) {
set<node*, cmp>s;
node *p = head;
while (p != NULL) {
node* q = p->next;
pair<set<node*, cmp>::iterator, bool> it = s.insert(p);
if (it.second == false) {
cout << "有环,第一个入环的值为" << p->data<<endl;
break;
}
p = q;
}
if (p == NULL)
cout << "无环";
}
void hoop2( node* head) {
if (head->next->next) {
node *slow ,*fast;
slow = fast = head->next;
while (fast->next != NULL && fast->next->next != NULL) {
slow = slow->next;//一次走一步
fast = fast->next->next;//一次走两步
if (fast == slow)
break; //相遇跳出循环
}
if (fast->next == NULL) {
cout << "无环" << endl;
}
else { //是因为fast == slow跳出循环 此时有环
fast = head->next;
while (fast != slow) {
slow = slow->next;//一次走一步
fast = fast->next;//一次走一步
}
cout << "有环,第一个入环的值为" << fast->data<<endl;
}
}
}
int main()
{
//------------尾差法建表----------------
node* head = new node;
head->next = NULL;
node *tail = head;
int a;
cin >> a;
while (a != -1) {
node *p = new node;
p->data = a;
p->next = tail->next;
tail->next = p;
tail = p;
cin >> a;
}
//------------尾差法建表----------------
tail->next = head->next->next;
hoop1(head);
hoop2(head);
return 0;
}