大橙子网站建设,新征程启航

为企业提供网站建设、域名注册、服务器等服务

环形链表C/C++数据结构-创新互联

目录

信州网站建设公司创新互联公司,信州网站设计制作,有大型网站制作公司丰富经验。已为信州上1000+提供企业网站建设服务。企业网站搭建\外贸营销网站建设要多少钱,请找那个售后服务好的信州做网站的公司定做!

什么是环?

例题 141. 环形链表

公式推导:

环形链表二  142. 环形链表 II

方法一:

方法二:

什么是环?

类似这种,结点下一个指针又指向链表本身,这样若遍历链表的话则会变成死循环。

特殊情况:自己也有可能成环

环的特点:

有两个指针指向环的起点

判断是否有环

例题 141. 环形链表

使用快慢指针,进入了环就变成了追及相遇的问题

思路:快指针一次走两步,慢指针一次走一步,当两个指针相遇时,即在链表中存在环

问题:为什么是快指针一次走两步?慢指针一次走一步?

bool hasCycle(struct ListNode *head) {
    //判断空链表
    if(!head){
        return NULL;
    }

    struct ListNode *slow=head;
    struct ListNode *fast=head;
    //判断条件是什么?
    //如果两个指针相等则有一个环
    //就把它当作一个正常数组想
    //因为只有这样才能从循环中出去
    //判断条件怎么想?
    while(fast&&fast->next)){
        fast=fast->next->next;
        slow=slow->next;
        //要是环的话根本出不去
        if(fast==slow){
            return true;
        }
    }
    return false;
}
公式推导:

假设链表中无环

快指针走的距离=2*慢指针走到距离

假设链表中有环

进环前的距离L,环的长度C,环的开始点至相遇点的距离X

慢指针走过的距离:L+X

快指针走过的距离:L+C*N+X

由此可以得出一个等式

L+X=N*C

L=(N-1)*C+C-X

意思是在入环前的长度==环的长度-(开始点至相遇点的距离)

也就是说: 蓝色部分=L

环形链表二 方法一:

本题首先需要找到相遇点,然后设立两个新的指针,两个指针从相遇点和起始点一起走,两个指针相遇的地方即为环形链表的起始点。

struct ListNode *detectCycle(struct ListNode *head) {
    //L=C-X
    //创立快慢指针
    struct ListNode *slow=head;
    struct ListNode *fast=head;
    //确保fast没有空指针
    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;
}
方法二:

使用相交链表的方式

先将链表从快慢指针的相遇点处断开

之后新建两个指针分别指向相遇点的下一位和原链表的头

利用相遇链表

相遇点即为起始点

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //想一想,极端情况
    //首先应该判断这两个链表不为空
    if(!headA||!headB)
        return NULL;
    
    //找到两个链表的最后一个节点
    struct ListNode *lastA=headA;
    int numA=1;
    while(lastA->next)
    {
        lastA=lastA->next;
        numA++;
    }

    struct ListNode *lastB=headB;
    int numB=1;
    while(lastB->next)
    {
        lastB=lastB->next;
        numB++;
    }
    //判断是否相交
    //这就是找最后一个节点的作用
    if(lastA!=lastB)
    {
        return NULL;
    }
    //找到长度,找最长的那个
    //不是说不能倒着走吗?难道是要它倒叙?
    //理解错了理解错了
    struct ListNode *lenglist=headA;
    struct ListNode *shortlist=headB;
    if(numAnext;
    }

    //两个一起走
    while(lenglist!=shortlist)
    {
        lenglist=lenglist->next;
        shortlist=shortlist->next;
    }

    //走到不相等时分开,返回相交的节点
    return lenglist;
}

struct ListNode *detectCycle(struct ListNode *head) {
    //L=C-X
    //创立快慢指针
    struct ListNode *slow=head;
    struct ListNode *fast=head;
    //确保fast没有空指针
    while(fast&&fast->next){
        //两者一起向前走
        slow=slow->next;
        fast=fast->next->next;
        //找到相遇
        if(slow==fast){
            struct ListNode *meet=slow;
            struct ListNode*next=meet->next;
            struct ListNode*walk=meet->next;
            meet->next=NULL;
            struct ListNode *newNode=getIntersectionNode(head,walk);
            meet->next=next;
            return newNode;
        }
    }
    return NULL;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文名称:环形链表C/C++数据结构-创新互联
分享网址:http://dzwzjz.com/article/dsshhd.html
在线咨询
服务热线
服务热线:028-86922220
TOP