【算法详解】有环链表
来源:互联网 发布: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
- 【算法详解】有环链表
- 算法详解
- 【算法详解】分治算法详解
- 【算法详解】洗牌算法
- 二分算法(折半算法)详解
- 【经典算法】详解 KMP 算法
- 【算法】【转】KMP算法详解
- 【算法】【转】KMP算法详解
- 【算法】Hash一致性算法详解
- [算法]详解关键路径算法
- 算法-详解堆排序算法
- PHP分页算法详解
- KMP算法详解
- Hash 算法详解
- 贪心算法的详解
- KMP算法详解
- KMP算法详解
- KMP算法详解
- [MDIT每天一小时]Android系统架构分析
- 初步认识bloom filter(布隆过滤器)以及java实现代码
- 解决firefox火狐浏览器占用内存大、启动慢问题的方法
- HDU 1753 大明A+B
- QQ聊天界面——QQ气泡效果与ListView
- 【算法详解】有环链表
- vi查找替换
- D_Double's Journey 的博客
- java error exception runtimeexception
- 将Lua嵌入IOS程序
- SPOJ MAXLN
- SPOJ MARBLES
- android draw9 patch介绍
- SPOJ PIGBANK