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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构--链表--单链表中环的检测,环的入口,环的长度的计算

發布時間:2024/7/5 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构--链表--单链表中环的检测,环的入口,环的长度的计算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

就如數字6一樣的單鏈表結構,如何檢測是否有6下部的○呢,并且求交叉點位置

思路

  • 使用快慢指針(一個一次走2步,一個走1步),若快慢指針第一次相遇,則有環
    慢指針路程 s=a+bs = a+bs=a+b
    快指針路程 2s=a+b+n?R2s = a+b+n*R2s=a+b+n?R
    s=n?Rs = n*Rs=n?R
    鏈表的長度 L=a+b+c=n?R+cL = a+b+c = n*R+cL=a+b+c=n?R+c
    L=a+RL = a + RL=a+R
    n?R+c=a+R?(n?1)?R+c=an*R+c = a+R \Rightarrow (n-1)*R+c = an?R+c=a+R?(n?1)?R+c=a
    意味著從head開始走到入口 aaa 步 == 從第一次相遇點走 n?1n-1n?1 圈 + 再走 ccc

  • 由上可以使快慢指針第一次到達相遇點時,使慢指針回到head,快指針仍在相遇點,然后兩人步伐一致,最后會在入口相見。

  • C++代碼實現:

    完整代碼見:https://github.com/hitskyer/course/tree/master/dataAlgorithm/chenmingming/linkedList

    類實現函數

    bool SingleList::hasLoop() {bool loop = false;ListNode fast = m_pHead, slow = m_pHead;ListNode posMeet = m_pHead, ringEntrance = m_pHead;//環的可能的入口應初始化成headif(m_pHead == NULL){loop = false;std::cout << "list has no loop!" << std::endl;}else{while(fast && fast->pNext){fast = fast->pNext->pNext;slow = slow->pNext;if(fast == slow){loop = true;posMeet = fast; //第一次相遇的地方break;}}slow = m_pHead; //接著讓慢指針回到表頭(這里是關鍵),繼續一起同步前行,第二次相遇的地方為環的入口while(slow != fast){slow = slow->pNext;fast = fast->pNext;if(fast == slow)ringEntrance = fast;}size_t lenOf_headToEntrance = howManyNode(m_pHead,ringEntrance);size_t ringLen_1 = howManyNode(ringEntrance->pNext, ringEntrance);std::cout << "len of head to ring entrance is " << lenOf_headToEntrance << std::endl;std::cout << "entrance Node is " << ringEntrance->data << std::endl;std::cout << "len of ring is " << ringLen_1 + 1 << std::endl;std::cout << "len of List is " << lenOf_headToEntrance + ringLen_1 + 1 << std::endl;}return loop; }size_t SingleList::howManyNode(ListNode ps, ListNode pe) //計算兩個指針之間有多少個節點(不包含第二個參數處的節點) {size_t count = 0;while(ps != pe){ps = ps->pNext;++count;}return count; }

    singleListIsLoop.cpp主函數

    // // Created by mingm on 2019/3/24. //檢查單鏈表中是否存在環,求環的長度,鏈表長度,及環的入口 #include <iostream> #include <time.h> #include <cstdlib> #include "./homework/singleList.cpp" using namespace std; int main() {srand((unsigned)time(NULL)); //用時間隨機數種子size_t len = 10; //測試鏈表最大長度for(size_t j = 1; j < len; ++j){SingleList intList;for(size_t i = 0; i < j; ++i){intList.AddTail(rand()%100); //添加隨機數到鏈表}cout << "no loop list: " << endl;intList.PrintList(); //排序前鏈表打印size_t n = rand()%(intList.GetLength()); //0-鏈表減1的隨機數ListNode randNode = intList.GetHeadNode();for(size_t i = 0; i != n; ++i){randNode = randNode->pNext; //鏈表的一個隨機節點}ListNode originTail = intList.GetTailNode();originTail->pNext = randNode; //尾節點接入鏈表中的隨機位置形成環intList.hasLoop(); //調用環檢測函數originTail->pNext = NULL; //斷開環,讓鏈表能夠按照單鏈表析構函數析構!!!!!!!std::cout << "getListLength() is " << intList.GetLength() << std::endl;std::cout << "-----------------------------------------" << std::endl;}return 0; }

    Valgrind檢測結果


    從鏈表長度1開始測試到9,測試結果均正確!

    總結

    以上是生活随笔為你收集整理的数据结构--链表--单链表中环的检测,环的入口,环的长度的计算的全部內容,希望文章能夠幫你解決所遇到的問題。

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