【C++编程题】高效判断单链表是否有环以及单链表的创建

在C++下,创建单链表并输出单链表的值:

#include<iostream>
#include<stdlib.h>>
using namespace std;

struct ListNode{
    int val;
    ListNode *next;
};

 class Solution{
  public: bool hasCycle(ListNode *head){
      if(head==NULL||head->next==NULL)
        {
            return false;
        }
        ListNode *slow,*fast;
        slow=head;
        fast=head;
//          ListNode *slow=head;
//          ListNode *fast=head;
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;

            if(fast==slow)
                return true;
            cout<<"标记2!";
        }
        cout<<"标记1!";
           return false;
    }
};
//构造链表是正确的
void build_list(ListNode *p){
     int vals;
    cout << "Input numbers!" << endl;
    while((cin>>vals)){
//        temp->val=vals;
          ListNode *t;
          t=(ListNode*)malloc(sizeof(ListNode));
          t->val=vals;
          p->next=t;
          p=p->next;
    }
}

int main()
{
    Solution sot;
    bool result;
    ListNode *p,*head;
    p=head;
    build_list(p);
    //输出
    cout<<"result is :"<<endl;
    for(p=head->next;p!=NULL;p=p->next){
        cout<<p->val<<"  ";
    }
    cout<<endl<<endl;
    result=true;
    result=sot.hasCycle(head->next);
    if(result)                //if result is true,there habe cycle,else not
        cout<<"There have cycle!"<<endl;
    else
        cout<<"There no cycle!"<<endl;
    return 0;
}

原本是Leetcode上的一个题目,在不借用额外空间下求单链表是否有循环。但是创建了单链表之后,不知道如何才能将单链表的弄成循环的,所以就仅仅是输出啦。
注意:这种方法的主要思想是定义两个指针fast和slow,slow每次走一步而fast一次走两步,最终如果没环的话,
链表遍历一遍就结束了;若是有环的话,快的链表肯定会与慢的链表相遇的。
之前一直有个思维误区,在有环的情况下fast一次跳两步会不会正好把slow跳过去呢?
后来发现是我多虑了,因为是每次一人走一步的,所以除了在起点以外,fast在环内是一直在slow后面的,而fast最接近slow的时候是离slow只有一步(就是fast->next是slow)或者是两步的。而fast离slow最近的时候两步之内肯定能追上slow。有兴趣的同学可以想一想就算是fast每次走三步,也是完全可以和slow碰面的。只不过要将while循环中多加一句判断语句:

slow=slow->next;
if(fast==slow)
   return true;
fast=fast->next->next->next;

至于原因嘛,~ _ ~ 你肯定能想到的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯拿铁go

你的打赏是我更新最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值