#include <stdio.h>
#include <stdlib.h>
/*找到环的入口节点的核心思路:
步骤:
1)、确认链表中有环
2)、计算环的长度
3)、获得环的入口
在获得环入口的时候,有如下公式:
(式子说明:快指针移动的距离:s 慢指针移动的距离:m
起点到入口点的距离:d 入口点到相遇点的距离:p 相遇点到入口点的距离:q
快指针在环内移动的圈数:n )
s = 2m; (1)
环长g:p+q
s = d+(p+q)*n+p (2)
m = d+p (3)
将(3)带入(1),得到:
s = 2*(d+p) (4)
将(4)带入(2),得到:
2*(d+p) = d+(p+q)*n+p
化简:
d + p = (p+q)*n
构造一下:
d+(p+q)-p = (p+q)*n
d = p+(p+q)*(n-1)
也就是说:在矢量图上,d距离入口点和p距离入口点的距离是相等的
*/
/*定义一个节点结构体*/
typedef struct node{
int data;
struct node *next;
}Node;
/*遍历链表*/
void travelList(Node *head)
{
head = head->next;
while(head)
{
printf("%d ",head->data);
head = head->next;
}
}
/*创建链表*/
Node * createList(int data)
{
Node *newList = (Node*)malloc(sizeof(Node));
/*判断分配内存是否成功*/
if(newList == NULL) printf("create fail \n");
newList->data = data;
newList->next = NULL;
return newList;
}
/*连接函数 用来创建循环链表(这个创建方式和之前的不一样)*/
void connectList(Node *node1,Node *node2)
{
node1->next = node2;
}
/*判断是否会相遇(是否有环) 有环,返回相遇的节点;没环,返回NULL*/
Node * findMeetNode(Node *head)
{
/*定义快慢指针*/
Node *sNode =NULL,*fNode=NULL;
/*指针定义*/
sNode = head->next;
fNode = sNode->next;
while(fNode != NULL)
{
/*相遇了*/
if(fNode == sNode)
{
return sNode;
break;
}
sNode = sNode->next;
fNode = fNode->next;
/*快指针移动的快。先移动一次,用if判断一下*/
if(fNode == NULL) return NULL;
/*快指针的步长是2,所以移两次*/
/*这次移动以后,用外层while判断一次*/
fNode = fNode->next;
}
return NULL;
}
/*判断环的入口*/
Node *EntryNode(Node *head)
{
/*初始值为快慢指针 相遇的节点*/
Node *meetNode = findMeetNode(head);
Node *headNode = head;
while(meetNode != headNode)
{
meetNode = meetNode->next;
headNode = headNode->next;
}
return headNode;
}
int main(void)
{
Node* pNode1 = createList(1);
Node* pNode2 = createList(20);
Node* pNode3 = createList(3);
Node* pNode4 = createList(41);
Node* pNode5 = createList(5);
Node* pNode6 = createList(6);
connectList(pNode1, pNode2);
connectList(pNode2, pNode3);
connectList(pNode3, pNode4);
connectList(pNode4, pNode5);
connectList(pNode5, pNode6);
connectList(pNode6, pNode2);
if(EntryNode(pNode1)!=NULL)
printf("%d",EntryNode(pNode1)->data);
else
printf("Error");
}
判断链表内是否有环以及环的入口节点(C语言实现) 附详细的代码注释
最新推荐文章于 2023-01-06 19:33:43 发布