亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言數據結構中單向環形鏈表怎么實現

發布時間:2022-04-11 15:22:28 來源:億速云 閱讀:158 作者:iii 欄目:開發技術

這篇“C語言數據結構中單向環形鏈表怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C語言數據結構中單向環形鏈表怎么實現”文章吧。

1、例題引入

鏈接直達:

環形鏈表

題目:

C語言數據結構中單向環形鏈表怎么實現

2、何為帶環鏈表

 正常的單鏈表每個節點順次鏈接,最后一個節點指向NULL,如下:

C語言數據結構中單向環形鏈表怎么實現

 而帶環鏈表的最后一個節點不再指向NULL了,指向的是前面任意一個節點,以此形成帶環鏈表,并一直循環下去。如下:

C語言數據結構中單向環形鏈表怎么實現

3、題解思路

我們可以將上述圖畫的抽象一點,在沒有進入環之前我們用直線表示,進入環之后用圈來表示,以此示意循環。此題需要用到我們之前講解的求中間節點和求倒數第k個節點的快慢指針的思想。定義兩個指針slow和fast均指向一開始的位置。 讓slow一次走一步,fast一次走兩步。

C語言數據結構中單向環形鏈表怎么實現

當slow走到直線一半的位置時,此時的fast剛好就在環的入口點。

C語言數據結構中單向環形鏈表怎么實現

假設slow剛好走到環的入口點時,fast走到如下位置,此時fast開始追趕模式

C語言數據結構中單向環形鏈表怎么實現

 fast開始追趕slow,假設fast在如下的位置開始追上slow

C語言數據結構中單向環形鏈表怎么實現

代碼如下:

bool hasCycle(struct ListNode *head) {
    struct ListNode*slow=head;
    struct ListNode*fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            return true;
        }
    }
    return false;
}

單純從解體的角度看,此題并不復雜,僅需用到快慢指針的思想即可解決,單是由此題可以引出多個值得我們探討的問題,以此來加深我們對環形鏈表的認知,如下三大拓展問題:

4、拓展問題

  • (1)slow一次走1步,fast一次走2步,一定能追上嗎?

 答案:一定能。

證明:

當slow走到中間的時候,fast一定進環了,此時fast開始追擊。我們假設slow進環以后,slow和fast的距離是N,此時slow走1步,fast走2步,它們倆的距離縮短1變為N-1。以此類推,每次追擊,距離縮小1,當距離縮小為0時就追上了。綜上,一定能追上。

C語言數據結構中單向環形鏈表怎么實現

  • (2)slow一次走1步,fast一次走3步,能追上嗎?fast一次走4步呢?n步呢?  

答案:不一定

證明:

我們先來討論slow一次走1步,fast一次走3步的情況。假設slow走了1步,fast走3步時剛好進環,而當slow剛好進環的時候,fast可能已經走了1圈,具體情況得看環的大小,此時slow和fast之間的距離為N。并假設環的長度是C。

slow一次走1步,fast一次走3步,距離變為N-2。由此可見,fast和slow每走一次,距離縮短2。此時就不難發現了,需要分類討論,當N是偶數時,剛好可以追上,當N是奇數時,追到最后距離為-1,此時就要再追了,意味著slow和fast之間的距離變成C-1。

繼續追擊,根據前面的分析,如果C-1是偶數,那么可以追上。如果C-1是奇數,那么就永遠追不上了,將會無線循環追下去,可就是追不上。他們的差距N是由進環前的長度和環的長度決定的,而這兩個又都是隨機的,所以N的值不確定,可奇可偶,又像剛剛那樣討論下去,出現奇數將一去不復返。

C語言數據結構中單向環形鏈表怎么實現

同理fast一次走4步也是這樣的討論,同樣都是不一定,不過這個時候是每走一次,距離縮短3。當N是3的倍數就可以追上,當不是3的倍數就要繼續討論了,有興趣的童鞋可以繼續鉆研下去,思想和fast一次走3步一樣,這里不過多贅述。

  • (3)鏈表環的入口點在哪呢?

 當我們搞清楚slow和fast分別走的距離時,入口點自然就明了了。

法一:

C語言數據結構中單向環形鏈表怎么實現

slow一次走1步,fast一次走2步,那么fast走的距離是slow的2倍

在具體講解之前,首先要搞清楚,不存在說慢指針slow在里頭走了一圈,快指針fast還沒有追到slow,因為fast每次走2步,slow每次走1步,它倆間的距離每次都縮小1,所以只會越來越近,直到追到。最多最多也就快1圈,但從來也不會剛好滿1圈。所以下面很容易推出slow和fast分別走了多少。

假設:

【鏈表頭 - - - 入口點】:L

【入口點 - - - 相遇點】:X

【環的長度】:C

C語言數據結構中單向環形鏈表怎么實現

slow走的距離:L + X

fast走的距離:L + N*C + X

解釋:

因為先前已經提到slow不會都走了一圈還沒被追到,所以很容易推出slow的距離就是L+X

而快指針一次走2步,很可能會因為環過小導致在slow指針進入入口點前,fast指針已經走了好幾圈。簡而言之3句話:

  • L很小,C很大,slow進環前,fast可能在環里面,一圈都沒走完

  • L很大,C很小,slow進環前,fast在里面走了很多圈了

  • 但是slow進環以后,在一圈之內,fast一定追到slow,它們的距離最多C-1

根據一開始說的,fast走的距離是slow走的距離的2倍,可列出如下式子:

2*(L+X) = L + N*C + X

化簡后:L+X = N*C     或    L = N*C - X     或     L = (N-1)*C + (C-X)     或     L + X = N*C

用此公式即可證明:一個指針從meet走,一個指針從head走,他們會在入口點相遇!

因為式子(N-1)*C表明從相遇點走了N-1圈后又回到了相遇點,此時再走C-X的距離就回到了入口點,由上得知,此公式確實讓它們回到了入口點。

用一道切實的題目來具體解出入口點的位置:鏈接直達:

環形鏈表2.0-->尋找入口點

題目:

C語言數據結構中單向環形鏈表怎么實現

 代碼如下:

struct ListNode* detectCycle(struct ListNode* head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        //判斷是否是帶環鏈表
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
        {
            struct ListNode* meet = slow;
            while (meet != head)
            {
                //求出相遇點
                meet = meet->next;
                head = head->next;
            }
            return meet;
        }
    }
    return NULL;
}

求相遇點還有另外一種方法:

找到相遇點meet后,讓meet做尾,讓下一個點做新鏈表的頭

C語言數據結構中單向環形鏈表怎么實現

以上就是關于“C語言數據結構中單向環形鏈表怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

连城县| 伊春市| 囊谦县| 黑山县| 锦州市| 通海县| 沂南县| 德化县| 荔波县| 乌海市| 阳山县| 兰坪| 连城县| 武平县| 惠来县| 剑阁县| 富蕴县| 宁海县| 开封市| 南靖县| 武陟县| 浦城县| 北安市| 黑山县| 三都| 高雄市| 鲁甸县| 东兰县| 阿拉善左旗| 西畴县| 苏州市| 三江| 万山特区| 延庆县| 谢通门县| 缙云县| 北碚区| 灵丘县| 旌德县| 清远市| 威远县|