標籤:

鏈表中環的入口節點

鏈表中環的入口節點

如果鏈表中包含環,如何找到入口節點?

思路:定義2個指針pfast和pslow,pfast指針每次走2步,pslow指針每次走1步,

如果走的快的指針最後追上走的慢的指針,則鏈表成環。

設:

慢指針走過的路程為s

出發點距離環入口點為a

環中相遇點距離入口點為b(走過的)

2個等式判斷環的入口點:

1.快指針走的路程是慢指針的2倍。

2s = s + nr==>s = nr

2.慢指針走過的路程

a + b = s

聯合1,2:

a = nr - b

因此,指針1從環內相遇點開始走,指針2從起點開始走,它們相遇點就是環的入口點。

參考代碼:

root@gt:/home/git/Code# ./a.out 0 1 2 3 4 5 6 7 8 9 10 11 12 pfast:2 pslow:1pfast:4 pslow:2pfast:6 pslow:3pfast:8 pslow:4pfast:10 pslow:5pfast:12 pslow:6pfast:11 pslow:7pfast:10 pslow:8pfast:12 pslow:9pfast:11 pslow:10pfast:10 pslow:11pfast:12 pslow:12has:1 meeting node:12enrty node:10root@gt:/home/git/Code# cat ring.c #include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct listNode{ int value; struct listNode* pnext;}ListNode;ListNode* entryNode(ListNode* phead,ListNode* pnode){ if(phead == NULL || pnode == NULL) return NULL; while(phead != pnode) { phead = phead->pnext; pnode = pnode->pnext; } return phead;}int hasRing(ListNode* phead,ListNode** ppnode){ if(phead == NULL) return 0; int ring = 0; ListNode* pslow = phead->pnext; ListNode* pfast = pslow->pnext; while(pfast != NULL && pslow != NULL) { printf("pfast:%d pslow:%d
",pfast->value,pslow->value); if(pslow == pfast) { ring = 1; *ppnode = pslow; break; } pslow = pslow->pnext; pfast = pfast->pnext->pnext; } if(pfast == NULL) ring = 0; return ring;}int main(){ ListNode* phead = (ListNode*)malloc(sizeof(ListNode)); phead->value = 0; phead->pnext = NULL; ListNode* plast = phead; for(unsigned int i = 1;i < 11 ;i++) { ListNode* pnew = (ListNode*)malloc(sizeof(ListNode)); pnew->value = i; pnew->pnext = NULL; plast->pnext = pnew; plast = pnew; } ListNode* pringNode2 = (ListNode*)malloc(sizeof(ListNode)); pringNode2->value = 12; pringNode2->pnext = plast; ListNode* pringNode1 = (ListNode*)malloc(sizeof(ListNode)); pringNode1->value = 11; pringNode1->pnext = pringNode2; plast->pnext = pringNode1; ListNode* ptmp = phead; for(int i = 0;i < 13;i++) { printf("%d ",ptmp->value); ptmp = ptmp->pnext; } printf("
"); ListNode* pnode = NULL; int has = 0; has = hasRing(phead,&pnode); printf("has:%d meeting node:%d
",has,pnode->value); ListNode* pentry = entryNode(phead,pnode); printf("enrty node:%d
",pentry->value); return 0;}root@gt:/home/git/Code#

推薦閱讀:

二進位中1的個數
二叉樹的鏡像
反轉鏈表
合併兩個排序的鏈表

TAG:演算法 | 筆試 |