C语言数据结构之判断单链表中是否有环

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1135004584/article/details/79329568

判断单链表中是否有循环链表的方法通常有两种:

/**方法一:
 *  2个指针,一个指针依次遍历,一个指针遍历所在位置次,若遍历次数不相等说明有闭合环路
 */
* 方法二:快慢指针,一个指针的移动速度是另一个指针移动速度的1倍,
* 如果当慢速的指针遍历过程中出现快指针和慢指针相等则说明有环

代码:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include <curses.h>
#include <stdbool.h>

typedef struct node{
    int id;
    struct node * next;
}Node,*LinkList;

void addNode(LinkList linkList,int id);
void initLinkList(Node ** linkList);


void randomNode(LinkList *pNode, int i);

void randomCir(LinkList *pNode, int i);

bool check_cir_fun_1(LinkList pNode);

bool check_cir_fun_2(LinkList pNode);

int main(void)
{
    LinkList linkList;
    initLinkList(&linkList);

    randomNode(&linkList,10);
    randomCir(&linkList,10);//随机产生一个环

//    if(check_cir_fun_1(linkList))
//    {
//        printf("有环\n");
//    }else{
//        printf("无环\n");
//    }

    if(check_cir_fun_2(linkList))
    {
        printf("有环\n");
    }else{
        printf("无环\n");
    }


    return 0;
}


/**方法一:
 *  2个指针,一个指针依次遍历,一个指针遍历所在位置次,若遍历次数不相等说明有闭合环路
 */

bool check_cir_fun_1(LinkList pNode)
{
    Node *pn1,*pn2,*temp;
    int j,k=j=0;
    temp = pn2 = pn1 = pNode->next;

    while(pn1->next)
    {
        pn1 = pn1->next;

        pn2 = temp;
        while(pn2 != pn1)
        {
            k++;
            pn2 = pn2->next;
        }
        j++;

        if(k!=j)
        {
            return true;
        }
        k = 0;
    }

    return false;
}



/**
 * 方法二:快慢指针,一个指针的移动速度是另一个指针移动速度的1倍,
 * 如果当慢速的指针遍历过程中出现快指针和慢指针相等则说明有环
 * @param pNode
 * @return
 */
bool check_cir_fun_2(LinkList pNode) {
    Node *pn1,*pn2;
    pn1 = pNode;
    pn2 = pNode;

    while(pn1->next && pn2->next)
    {
        pn1 = pn1->next;

        if(pn2->next->next)
            pn2 = pn2->next->next;
        else
            pn2 = pn2->next;

        if(pn1 == pn2)
            return true;

    }


    return false;
}

void randomCir(LinkList *pNode, int i) {
    Node * pn = (*pNode)->next;
    srand((unsigned)time(NULL));//置随机数种子

    int k = rand()%i;// 0-i内随机找一个位置
    int n=0;
    while(pn->next && n<k)
    {
        n++;
        pn = pn->next;
    }

    pn->next = (*pNode)->next->next;//随机一节点与第二个节点接上,形成闭合环路
}

void randomNode(LinkList *pNode, int i)
{
    srand((unsigned)time(NULL));//置随机数种子
    for(int k=0;k<i;k++)
        addNode(*pNode, rand() % i);
}

//用头插法
void addNode(LinkList linkList,int id)
{
    Node * n = (Node *)malloc(sizeof(Node));
    n->id = id;
    n->next = linkList->next;
    linkList->next = n;
}
//链表的初始化操作
void initLinkList(Node ** linkList)
{
    (*linkList) = (Node *)malloc(sizeof(Node));
    (*linkList)->next = NULL;
}


运行结果:


猜你喜欢

转载自blog.csdn.net/a1135004584/article/details/79329568