#include <stdio.h>
#include <stdlib.h>
struct node
{
int hao;
int val;
int data;
struct node *next;
};
void showlist(struct node *head)//打印链表
{
printf("========open=======\n");
while(head)
{
sleep(1);
printf("编号 %d head->val %d\n", head->hao, head->val);
head = head->next;
}
printf("========over=======\n");
}
void insert_Head(struct node **h, struct node *n)//头插
{
n->next = *h;
*h = n;
}
struct node *insert_tail(struct node *head, struct node *new)//尾插(有返回值)
{
if(head == NULL)
{
return new;
}
struct node *p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = new;
return head;
}
void insert_Tail(struct node **h, struct node *n)//尾插(无返回值)
{
while(*h)
{
h = &((*h)->next);
}
*h = n;
}
void loop(struct node *h)//把链表变成一个环
{
struct node *p = h;
struct node *t = h;
while(p->next)
{
p = p->next;
}
while(t->next)
{
if(t->val == 40)
{
p->next = t;
return;
}else
{
t = t->next;
}
}
}
void exit_loop(struct node *h)//判断是否有环,并找到环的入口
{
struct node *slow = NULL;
struct node *fast = NULL;
slow = fast = h;
while(slow != NULL && fast != NULL && fast->next != NULL)
{
//让一个慢一个快
slow = slow->next;
fast = fast->next->next;
if(fast == slow)
{
printf("有环\n");
//链表的头到入口点和相遇的节点到入口点恒等于
struct node *p = fast;
struct node *head = h;
while(p != head)
{
p = p->next;
head = head->next;
}
printf("入口点 %d\n", head->val);
return;
}
}
printf("无环\n");
return ;
}
int listlen(struct node *h)//链表的长度
{
struct node *slow = NULL;
struct node *fast = NULL;
struct node *p = NULL;
int tmp = 0;
slow = fast = h;
while(slow != NULL && fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if(fast == slow)
{
p = fast;
break;
}
}
while(h != p)
{
h = h->next;
tmp++;
}
return tmp;
}
int main()
{
int arr[] = {10,20,30,40,50,60,70,20,30,63};
struct node *head = NULL;
struct node *newnode = NULL;
int i = 0;
int n = sizeof(arr)/sizeof(int);
while(i < sizeof(arr)/sizeof(int))
{
newnode = malloc(sizeof(struct node));
newnode->val = arr[i];
newnode->hao = i;
newnode->next = NULL;
insert_Tail(&head, newnode);
i++;
}
loop(head);
exit_loop(head);
printf("list_len %d\n", listlen(head) );
// showlist(head); //链表遍历
return 0;
}