【算法详解】有环链表

来源:互联网 发布:linux 命令 r 编辑:程序博客网 时间:2024/06/15 06:49

定义:

循环链表:链表中一个节点的next指针指向先前已经存在的节点,导致链表中出现环。



问题1:判断是否有环

#include <cstring>#include <iostream>using namespace std;struct node{char value;node* next;node(char rhs){value = rhs;    next = NULL;}};bool isLoop(node* head){    if (head == NULL){    return false;}node* slow = head;node* fast = head;while((fast!= NULL) && (fast->next != NULL)){    slow = slow->next;fast = fast->next->next;if (slow == fast){break;}}return !(fast == NULL || fast->next == NULL);}int main() {    node A('A');node B('B');node C('C');node D('D');node E('E');node F('F');node G('G');node H('H');node I('I');node J('J');node K('K');A.next = &B;B.next = &C;C.next = &D;D.next = &E;E.next = &F;F.next = &G;G.next = &H;H.next = &I;I.next = &J;J.next = &K;K.next = &D;if (isLoop(&A)){    cout<<"Loop";}else{cout<<"No loop";}return 0;}


问题2:找到这个环的起始点

输入: A->B->C->D->E->F->G->H->I->J->K->D

输出:D

分析:


当fast与slow相遇时, slow肯定没有遍历完链表,而fast在环内肯定循环了1圈以上。

设环的长度为r, 相遇时fast在环内走了n个整圈(n > 1),slow走了s步,fast走了2s步,则:

2s = s + nr    ->  s = nr

设整个链表的长度为L,环入口点与相遇点的距离为x,链表起点到环入口点的距离为a,则:

a + x = s = nr    (slow走过的步数,slow为走过一圈)

a + x = (n-1)r + r = (n-1)r + (L - a)    ->  a = (n-1)r + (r - x)

(r - x) 为相遇点到环入口点的距离; 因此,链表头到环入口点的距离 等于 (n-1)个环循环 + 相遇点到环入口的距离。

我们从链表头和相遇点分别设置一个指针,每次各走一步,则两个指针必定相遇,且第一个相遇点为环入口点

#include <cstring>#include <iostream>using namespace std;struct node{char value;node* next;node(char rhs){value = rhs;next = NULL;}};node* isLoop(node* head){if (head == NULL){return false;}node* slow = head;node* fast = head;while((fast!= NULL) && (fast->next != NULL)){slow = slow->next;fast = fast->next->next;if (slow == fast){break;}}   if (fast == NULL || fast->next == NULL)   {   return NULL;   }   // currently, the list is looped   slow = head;   while(slow != fast)   {   slow = slow->next;   fast = fast->next;   }   return slow;}int main() {node A('A');node B('B');node C('C');node D('D');node E('E');node F('F');node G('G');node H('H');node I('I');node J('J');node K('K');A.next = &B;B.next = &C;C.next = &D;D.next = &E;E.next = &F;F.next = &G;G.next = &H;H.next = &I;I.next = &J;J.next = &K;K.next = &D;node* p;if ((p= isLoop(&A))!= NULL){cout<<"Loop, the interaction node is "<<p->value;}else{cout<<"No loop";}return 0;}





0 0
原创粉丝点击