判断单链表是否有环的两种方法

如图,如果单链表有环,则在遍历时,在通过6之后,会重新回到3,那么我们可以在遍历时使用两个指针,看两个指针是否相等。



方法一:使用p、q两个指针,p总是向前走,但q每次都从头开始走,对于每个节点,看p走的步数是否和q一样。如图,当p从6走到3时,用了6步,此时若q从head出发,则只需两步就到3,因而步数不等,出现矛盾,存在环

方法二:使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p == q,则存在环。

代码如下:

#include <stdio.h>
#include <stdlib.h>

#define LEN 8
typedef struct node* node_t;

struct node{
    char val;
    struct node *next;
};  

//method 1
int has_loop(struct node *head);
//method 2
int has_loop2(node_t head);

int main()
{
    node_t* arr = (node_t*)malloc(sizeof(struct node)*LEN);
    arr[0] = (node_t)malloc(sizeof(struct node));
    int i;
    for(i = 1; i < LEN; i++)
    {
        arr[i] = (node_t)malloc(sizeof(struct node));
        arr[i - 1]->next = arr[i];
    }
    arr[LEN - 1]->next = NULL;

    //you can add a loop here to test
    //arr[6]->next = arr[0];
    if (has_loop(arr[0]))
        printf("method1: has loop.\n");
    else
        printf("method1: has no loop.\n");

    if (has_loop2(arr[0]))
        printf("method2: has loop.\n");
    else
        printf("method2: has no loop.\n");

    return 0;
}

//if two pointer are equal, but they don't have the same steps, then has a loop
int has_loop(node_t head)
{
    node_t cur1 = head;
    int pos1 = 0;
    while(cur1){
        node_t cur2 = head;
        int pos2 = 0;
        pos1 ++;
        while(cur2){
            pos2 ++;
            if(cur2 == cur1){
                if(pos1 == pos2)
                    break;
                else
                    return 1;
            }
            cur2 = cur2->next;
        }
        cur1 = cur1->next;
    }
    return 0;
} 

//using step1 and step2 here
//if exists a loop, then the pointer which use step2 will catch up with the pointer which uses step1
int has_loop2(node_t head)
{
    node_t p = head;
    node_t q = head;
    while (p != NULL && q != NULL)
    {
        /*
        p = p->next;
        if (q->next != NULL)
            q = q->next->next;
        if (p == q)
            return 1;
            */
        //correct it on 17/11/2012
        p = p->next;
        q = q->next;
        if (q != NULL)
            q = q->next;
        if (p != NULL && p == q)
            return 1;
    }
    return 0;
}
时间: 2024-09-30 08:33:07

判断单链表是否有环的两种方法的相关文章

判断iPhone的WiFi是否打开的两种方法_IOS

判断WiFi是否连接可以使用Reachability进行判断,那么WiFi是否打开应该怎么判断呢? 下面是两种完全基于不同思路的方法: 方法一: 使用SystemConfiguration.framework 库进行判断 #import <ifaddrs.h> #import <net/if.h> #import <SystemConfiguration/CaptiveNetwork.h> - (BOOL) isWiFiEnabled { NSCountedSet *

PHP代码判断设备是手机还是平板电脑(两种方法)_php实例

现在移动互联网越来越发达,很多的网站都普及了手机端浏览,为了更好的让网页在手机端显示,我们都选择了使用CSS媒体查询制作响应式模版,但这也有弊端,例如某些网站的结构是CMS类型的,太多的内容要显示,而使用CSS媒体查询设计响应式,只会隐藏但还是加载了,为了让手机端更快速的显示出内容,我们可以使用这个PHP判断手机设备代码,使用这个代码可以很方便的显示或不显示自定义的内容. 在做WEB开发的时候经常会需要用到对移动设备的页面匹配,当然可以直接把网站做成响应式的,但如果不想这么做的话,可以使用PHP

求有环单链表中的环长、环起点、链表长

1.判断单链表是否有环 使用两个slow, fast指针从头开始扫描链表.指针slow 每次走1步,指针fast每次走2步.如果存在环,则指针slow.fast会相遇:如果不存在环,指针fast遇到NULL退出. 就是所谓的追击相遇问题: 2.求有环单链表的环长   在环上相遇后,记录第一次相遇点为Pos,之后指针slow继续每次走1步,fast每次走2步.在下次相遇的时候fast比slow正好又多走了一圈,也就是多走的距离等于环长. 设从第一次相遇到第二次相遇,设slow走了len步,则fas

判断窗体是否打开的两种方法

判断窗体是否打开的两种方法 Function IsLoaded(strName As String, Optional intObjectType As Integer = acForm) IsLoaded = (SysCmd(acSysCmdGetObjectState, intObjectType, strName) <> 0) End Function 函数二 Function IsFormLoaded(strFrmName As String) As Boolean Const con

js判断字符是否是汉字的两种方法小结

 本篇文章主要是对js判断字符是否是汉字的两种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 有时需要判断一个字符是不是汉字,比如在用户输入含有中英文的内容时,需要判断是否超过规定长度就要用到.用 Javascript 判断通常有两种方法.    1.用正则表达式判断    代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org

js判断url是否有效的两种方法

本篇文章主要是对js判断url是否有效的两种方法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 方法一:(仅适用于ie)    代码如下: function CheckStatus(url)         {             XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP")             XMLHTTP.open("HEAD",url,false)             XMLHT

Jquery中ajax提交表单几种方法(get、post两种方法)_AJAX相关

在jquery中ajax提交表单有post与get方式,在使用get方式时我们可以直接使用ajax 序列化表单$( 表单ID) serialize();就行了,下面我来介绍两个提交表单数据的方法.$get方式提交表单get() 方法通过远程HTTP ,下面我来介绍两个提交表单数据的方法. $get方式提交表单 get() 方法通过远程 HTTP GET 请求载入信息 格式 $(selector).get(url,data,success(response,status,xhr),dataType

c#利用webservice和wcf对oracle数据库增删改查,并判断两种方法的效率

问题描述 c#利用webservice和wcf对oracle数据库增删改查,并判断两种方法的效率 初学者,以前没有接触过webservice和wcf.现在遇到一个这样的项目,请大家给予帮助,提供源码,思路都行.当然,最好是代码了,亲,帮一个忙呗~ 解决方案 ws相对简单,WCF就是一把大牛刀,虽然很好,但是你要是杀鸡就得不偿失了.你是了解MVC的话,通信可以试试WebAPI.例子网上到处都是的

通过JS和PHP两种方法判断用户请求时使用的浏览器类型_javascript技巧

在进行微信公众账号开发的时候,其中很大一块是微站点的开发,我们需要知道当前的浏览器是微信内置的浏览器,那么如何判断呢? 微信内置浏览器的 User Agent 如何判断微信内置浏览器,首先需要获取微信内置浏览器的User Agent,经过在 iPhone 上微信的浏览器的检测,它的 User Agent 是: Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko)