判断链表是否成环,如果成环返回成环的第一个结点

#include <stdio.h>
#include <stdlib.h>
typedef struct LinkNode
{
    struct LinkNode* next;
    int data;
}LinkList;
/*说明:都带头结点的单链表*/
/*创建链表*/
void createLinkList(LinkList* head, int* a, int n)
{
    int i = 0;
    LinkNode* node = NULL;
    while (i < n)
    {
        node = new LinkNode;
        node->next =  head->next;
        node->data = a[i];
        head->next = node;
        i++;
    }
}
/*判断链表是否为环,如果为环返回环的结点*/
bool isCircleList(LinkList* head, LinkNode* &headNode)
{
   LinkNode* fast = head;
   LinkNode* slow = head;

   while (fast != NULL)
   {
        if (fast->next != NULL)
        {
            fast = fast->next; /*快指针走两步*/
        }
        fast = fast->next;
        slow = slow->next; /*慢指针走一步*/
        if (fast == slow)  /*相遇则跳出*/
        {
            break;
        }
   }

   /*走到终点,返回FALSE*/
   if (fast == NULL)
   {
        return false;
   }

   /*可以证明:头指针 到 环入口的距离 = 碰撞点p 到 环入口的距离   +  循环多次环*/
   /*参考:http://blog.csdn.net/xiaodeyu2010xiao/article/details/42460203*/
   /*让fast从起点开始走,让slow继续往下走,相遇点就是环的入口*/
   fast = head;
   while (fast != slow)
   {
       fast = fast->next;
       slow = slow->next;
   }
   headNode = slow;
   return true;

}

/*k表示从第K个成环*/
bool createCircleList(LinkList* head, int k)
{
     LinkNode* node;
     LinkNode* lastNode = head;

     while (lastNode->next != NULL)
     {
        lastNode = lastNode->next;
        k--;
        if (k == 0)
        {
            node = lastNode;
        }
     }

     if (k > 0)
     {
        return false;
     }
     lastNode->next = node;/*成环*/
     return true;
}

/*打印链表*/
void printLinkList(LinkList* head)
{
    LinkNode* node = head->next;
    while (node != NULL)
    {
        printf("%d\t", node->data);
        node = node->next;
    }
    printf("\n");
}
int main()
{
    LinkList head = {0};
    LinkNode* node = NULL;
    int a[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
    createLinkList(&head, a, 9);
    printLinkList(&head);
    createCircleList(&head, 3);
    isCircleList(&head, node);
    if (node != NULL)
    {
        printf("circle node is: %d\n", node->data);
    }
    return 0;
}

时间: 2024-10-11 21:46:07

判断链表是否成环,如果成环返回成环的第一个结点的相关文章

链表(13)----判断链表是否有环,并返回环入口节点

1.链表定义 typedef struct ListElement_t_ { void *data; struct ListElement_t_ *next; } ListElement_t; typedef struct List_t_{ int size; int capacity; ListElement_t *head; ListElement_t *tail; } List_t; 2.判断链表是否有环,并返回链表入口节点 (1)方法一:根据相遇节点.头结点.入口节点之间的距离关系求解

《编程之美》3.6判断链表是否相交之扩展:链表找环方法证明

先看看原题:<编程之美>3.6编程判断两个链表是否相交,原题假设两个链表不带环. 为了防止剧透使得没看过原题目的读者丧失思考的乐趣,我把最好的解法隐藏起来.由于这个问题本身的解答并不是本文的重点,扩展问题也采用这种形式呈现. 注:位于(*)符号之间的文字出自于:http://blog.csdn.net/v_july_v/article/details/6447013,作者v_JULY_v. 用指针p1.p2分别指向两个链表头,不断后移:最后到达各自表尾时,若p1==p2,那么两个链表必相交 用

C语言强化(七)链表相交问题_3 判断链表是否带环

前两篇讨论的前提都是链表是无环的,但是如果链表有环呢? 显然,如果链表有环,那么之前的寻找链表尾结点的函数将陷入死循环,之前的算法也将崩掉. 所以对于链表相交的问题,首先要判断的是链表是否有环. 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路 用两个指针,一个指针步长为1,一个指针步长为2,若最后相遇,则链表有环

链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习

判断链表是否有环及两链表是否相交

单向链表是最常用的数据结构之一,因此总结其常见的问题及其解决方案是很有意义的. 问题1:如何判断一个单向链表是否有环?如果有,如何找到其入口节点的指针? 算法思想:用两个指针p1,p2同时指向链表的头部,p1一次移动一步,p2一次移动两步,如果最终p1和p2重合则说明链表有环,如果p2走到空指针(链表的结尾)则说明链表无环: 如果最终p1和p2重合,使p2重新指向链表的头结点,然后p1和p2同时一次移动一步,当p1和p2再次重合时该节点指针就是环的入口节点指针. 算法实现: [cpp] view

Q:判断链表中是否存在环的相关问题

问题:如何判断一个单向链表中是否存在环? 例如: 链表中存在环(B-->D): <-- <--^ | | v | A-->B-->C-->D 链表中不存在环: A-->B-->C-->D-->E-->F 解题思路: ??从一个实际的生活场景出发,两个人,在一个环形的操场上跑步的时候,如果有一个人跑得比另一个人还要快,那么,在n圈之后,这两个人总会在操场上的某个点相遇.将操场类比于链表中存在的环路径,将两个人看成两个指针,那么这道题的解题思路

链表:判断链表是否带环 、求两个链表的相交结点

问题一:返回两个链表的相交结点1.先分别得到两个链表的长度2.得到长度差,3.先让长链表的头结点走(长度差)步.4.这时.短链表头结点还在原地,两者开始一起走,当得到两者val相等时,这个结点就是公共结点,即相遇结点. 问题二:判断链表是否带环1.定义两个快慢指针,快指针先走两步,慢指针再走一步.直到快慢指针当前结点相同. 如果快指针先为null,则表示没有环,返回null.2.如果带环,让起点和相遇点同时出发.同走一步,再判断相等与否,如果相等退出循坏 返回这个结点 ```public cla

判断链表是否有环

Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space? 关键点:1)判断链表是否有环. 2)一个小坑在判断root和root的next是否为空上. 3)可以看为追及问题.最关键的坑在判断快走(每次走2步的节点),走1步会不会已经走到头... /** * Definition for singly-linked list. * str

如何判断链表相交

链表相交:对于链表而言,两个链表如果相交就会合并成一个后继,之后后继成为一个链表.根据相交的理论可以建立出两个简单的链表相交. 当用户在第一个链表中输入10的那个点作为要相交的那个点,第二个链表输入零之后就与第一个链表的10那个点相交. 代码如下: 1 #include <stdio.h> 2 typedef struct Linklist{ 3 int num; 4 struct Linklist *next; 5 }list; 6 7 struct Linklist *in; 8 9 vo