判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點?
阿新 • • 發佈:2018-11-01
判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點?
這道題有三問,是否帶環?環的長度?環的入口點?
1.單鏈表是否帶環?
思路分析:怎麼樣才算帶環呢?我們細想,如果一個單鏈錶帶環的話,那麼它怎麼走都走不出來的,而如果不帶環的話,那麼一定會走到NULL的。
設定快慢指標,剛開始都指向連結串列的起始位置,快指標一次走兩步,慢指標一次走一步,如果兩個指標相遇,則帶環;若快指標走到NULL,則不帶環。
程式碼:
Node *IsCircleList(Node *list) { Node *fast = list; Node *slow = list; if (list == NULL || list->next == NULL) { return NULL; } while (fast&&fast->next) { fast = fast->next->next;//快指標一次走兩步 slow = slow->next;//慢指標一次走一步 } if (fast == slow) { return fast;//如果相等,返回相遇點 } }
2.求環的長度?
思路分析:當我們已經知道了這個連結串列是帶環的,那麼環的長度又該如何求呢?
首先我們上一步已經確定這個連結串列帶環,並且找到了快慢指標的相遇點,那麼我們就可以從相遇點開始再走一圈,每走一步計數,當再次走到相遇點的時候,便求出了環的長度。
程式碼:
int GetCircleLen(Node *list) { Node *p = IsCircleList(list); int count = 0; if (p != NULL)//帶環 { while (p->next != p) { count++; p = p->next; } count++;//加上最後一個結點 } return count; }
3.求環的入口點
思路分析:這一步個人覺得有點變態,因為需要用到數學推導證明。我在這裡以圖的形式分析比較清楚一下,如下圖:
程式碼:
Node *EnterNode(Node *list) { Node *node = IsCircleList(list); Node *first = list; if (node != NULL)//帶環 { while (node != first) { node = node->next; first = first->next; } } return node; }