• [数据结构] 单链表如何判环以及求环的长度,入口


    目录

    如何判环?

    如何求环的长度?

    如何求环的入口呢?

    示例


    如何判环?

    思路: 利用两个移动速度不同的指针,若在均不为空的情况下相遇,则存在环

    如何求环的长度?

    思路:若存在环,那么快慢指针从相遇点重新出发到再次相遇的过程中, 一定是慢指针走了一圈,快指针走了两圈, 慢指针所走过的步数即为环的长度

    如何求环的入口呢?

    推理:

     所以,我们在相遇点位和链表的起点分别设立两个速度相同的指针,当他们相遇时即在环的入口

    示例

    其中测试数据的关系如图

    #include<iostream>
    using namespace std;
    
    typedef struct SingleListNode{
        int value;
        SingleListNode* next;
        SingleListNode(int v):value(v),next(NULL){}
    }SLNode;
    
    class SingleList{
        public:
            SLNode* phead;
            SingleList();
            bool isCircle(){
                return firstMeet(phead) != NULL;
            }
            int getCircleLenth();
            int getCircleEntrance();
            void headInsert(int value);
    
        private:
            
            SLNode* firstMeet(SLNode* phead);
    
    };
    
    SingleList::SingleList()
    {
    	phead = new SLNode(0);
    }
    
    void SingleList::headInsert(int value)
    {
        SLNode* newNode = new SLNode(value);
        newNode->next = phead->next;
        phead->next = newNode;
    }
    
    SLNode* SingleList::firstMeet(SLNode* phead)
    {
        SLNode* pslow, *pfast;
        pslow = pfast = phead->next;
    
        while(pslow && pfast)       //若存在环的话两个工作指针必不会出现空的情况
        {
            pslow = pslow->next;
            pfast = pfast->next ? pfast->next->next : pfast->next;
    
            if(pslow->value == pfast->value) return pslow;
        }
        return NULL;       
    }
    
    int SingleList::getCircleLenth()
    {
        SLNode* pfirstMeet = firstMeet(phead);
        
        //无环的情况
        if(!pfirstMeet) return 0;
    
        SLNode* pslow, *pfast;
        pslow = pfast = pfirstMeet;
        int step = 0;
        while(pslow && pfast)
        {
            pslow = pslow->next;
            step ++;
            pfast = pfast->next ? pfast->next->next : pfast->next;
            if(pslow->value == pfast->value) return step;
        }
    }
    
    int SingleList::getCircleEntrance()
    {
        SLNode* pfirstMeet = firstMeet(phead);
        
        //无环的情况
        if(!pfirstMeet) return -1;
    
        SLNode* p1 = phead->next;
    	SLNode* p2 = pfirstMeet;
    
        while(p1 != p2)
        {
            p1 = p1->next;
            p2 = p2->next;
        }
        return p1->value;
    }
    
    int main()
    {
        SingleList* list = new SingleList();
        
        SLNode* p1 = new SLNode(1);
        SLNode* p3 = new SLNode(3);
        SLNode* p5 = new SLNode(5);
        SLNode* p7 = new SLNode(7);
        SLNode* p2 = new SLNode(2);
        SLNode* p4 = new SLNode(4);
    
        p1->next = p3;
        p3->next = p5;
        p5->next = p7;
        p7->next = p2;
        p2->next = p4;
        p4->next = p5;
        list->phead->next = p1;
        
        if(list->isCircle()){
        	cout << "存在环,且长度为: " << list->getCircleLenth() <<  endl; 
         	cout << "环的入口为: " << list->getCircleEntrance(); 
    	}else{
    		cout << "不存在环" ; 
    	}
    
        return 0;
    }

    输出:

    本文来自博客园,作者:泥烟,CSDN同名, 转载请注明原文链接:https://www.cnblogs.com/Knight02/p/15799006.html

  • 相关阅读:
    Laravel 框架
    tp5
    jq关于对象类型的判断
    简易的 js 留言板
    学习任务
    实验报告:指针与地址
    C语言数据类型
    嗯,关于 nanxI 的50条~(算是自我介绍吧)
    初学C语言
    dropload.js
  • 原文地址:https://www.cnblogs.com/Knight02/p/15799006.html
Copyright © 2020-2023  润新知