日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【☘️C语言の单链表是否有环问题☘️】

發布時間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【☘️C语言の单链表是否有环问题☘️】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題:

給定一個單鏈表,只給出頭指針,如何判斷是否存在環?

思路:

使用快慢指針法
使用兩個指針(快指針(fast)、慢指針(slow))從鏈表頭開始遍歷此單鏈表。快指針每次走兩步,慢指針每次走一步。
如果有環:快指針和慢指針會相遇;
如果無環:快指針走到單鏈表尾部,遇到NULL退出。

類比思維:

就是小學數學經常考的龜🐢兔🐰賽跑追擊相遇問題:
小兔子🐰速度快,小烏龜🐢速度為慢。它們從起點一起出發,賽道如果有環,他們一定都會在環里不停地跑,它們總歸相遇;如果賽道沒有環,小兔子🐰肯定很早就達到終點,比賽結束啦。

代碼:

以下圖單鏈表為例

#include <stdio.h> #include <stdlib.h>typedef struct node {int value;struct node *next; }LinkNode, *Linklist;Linklist createList(); ///< 創建單鏈表 int deleteList(Linklist head, LinkNode* cyclestartnode); ///< 刪除單鏈表 LinkNode* judgeCycle(Linklist head); ///< 判斷單鏈表是否有環///< 法一 int getLenHead2CycleStart(Linklist head, LinkNode *cycleMeetNode); ///< 獲取頭結點到環入口結點長度 LinkNode* CycleStart(Linklist head, int len); ///< 根據頭結點到環入口結點長度獲取環入口結點///< 法二 LinkNode* getCycleStartNode(Linklist head); ///< 獲取環入口結點int main() {Linklist list = NULL; ///< 已知單鏈表LinkNode *cycleMeetNode = NULL; ///< 快慢指針相遇結點LinkNode *cycleStartNode = NULL; ///< 環入口結點int Len = 0;int cycleLength = 0;list = createList();cycleMeetNode = judgeCycle(list); if (cycleMeetNode == NULL){printf("No Cycle\n");}else{printf("Have Cycle\n");///< 獲取環起始點///< 法一//Len = getLenHead2CycleStart(list, cycleMeetNode);// cycleStartNode = CycleStart(list, Len); ///< 法二cycleStartNode = getCycleStartNode(list);}deleteList(list, cycleStartNode); ///< 刪除單鏈表, 有環時需要注意環起始點return 0; }/// 創建鏈表(鏈表長度,環節點起始位置) Linklist createList() {Linklist head = NULL;LinkNode *preNode = head;LinkNode *tailNode = NULL;int i = 0;for (i = 0; i < 7; i++){LinkNode *pLinkNode = (LinkNode*)malloc(sizeof(LinkNode));pLinkNode->value = i;pLinkNode->next = NULL;if (preNode == NULL){head = pLinkNode;preNode = head;}else{preNode->next = pLinkNode;preNode = pLinkNode;}if (3 == i){tailNode = pLinkNode;}}preNode->next = tailNode;return head; }///< 刪除鏈表 int deleteList(Linklist head, LinkNode* cyclestartnode) {int isCycleStartFlag = 0; ///< 環起始點只能被釋放空間一次 isCycleStartFlag:0 表示沒有被釋放過 ,1 表示已經被釋放過LinkNode *nextnode = NULL;while (head != NULL){nextnode = head->next;///< 如果是環起始結點if (head == cyclestartnode){if (1 == isCycleStartFlag){break; ///< 如果第二次遇到環起始點,則停止。此時鏈表已經刪除完畢}else{isCycleStartFlag = 1; ///< 記錄:已經釋放過了}}free(head);head = nextnode;}return 0; }///< 判斷鏈表是否有環,如有返回相遇結點,無則返回NULL LinkNode* judgeCycle(Linklist head) {LinkNode *fastNode = head;LinkNode *slowNode = head;if (head == NULL){return NULL;}while (1){if (slowNode->next != NULL && fastNode->next != NULL && fastNode->next->next != NULL){slowNode = slowNode->next; ///< 慢指針:一步fastNode = fastNode->next->next; ///< 快指針:兩步}else{return NULL;}if (fastNode == slowNode){return fastNode;}}return NULL; }///< 法一 ///< 獲取鏈表頭到環連接點的長度 int getLenHead2CycleStart(Linklist head, LinkNode *cycleMeetNode) {int lenA = 0;LinkNode *aNode = head; ///< 從頭結點開始 LinkNode *bNode = cycleMeetNode; ///< 從相遇點開始while (1){aNode = aNode->next;bNode = bNode->next;lenA++;if (aNode == bNode)break;}return lenA; }///< 獲取環入口結點 LinkNode* CycleStart(Linklist head, int len) {if (!head || len <= 0){return NULL;}int i = 0;LinkNode* tmp = head;for (; i < len; ++i){if (tmp != NULL){tmp = tmp->next;}}return (i == len) ? tmp : NULL; }///< 法二 ///< 獲取環入口結點 LinkNode* getCycleStartNode(Linklist head) {LinkNode *fastNode = head;LinkNode *slowNode = head;int isHaveCycle = 0;if (NULL == head){return NULL;}///< 快慢指針法判斷是否有環,有環則找出相遇點while (slowNode->next && fastNode->next && fastNode->next->next){slowNode = slowNode->next;fastNode = fastNode->next->next;if (slowNode == fastNode){isHaveCycle = 1;break;}}if (1 == isHaveCycle){slowNode = head;///< 一個從頭結點出發,一個從相遇點觸發,再次相遇則為環入口節點while (slowNode != fastNode){slowNode = slowNode->next;fastNode = fastNode->next;}return slowNode;} else{return NULL;} }

打印信息:

Have Cycle

引經據典

http://blog.sina.com.cn/s/blog_725dd1010100tqwp.html
http://www.cnblogs.com/xudong-bupt/p/3667729.html

總結

以上是生活随笔為你收集整理的【☘️C语言の单链表是否有环问题☘️】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。