#include<stdio.h>
#include<stdlib.h>
typedef struct LNode{
int data;
struct LNode* next;
}LNode,*LinkList;
//创建没有头结点的单链表,如果没有元素则单链表的head=NULL
LinkList create_link()
{
LinkList head,newNode,preNode;
int x;
head=(LinkList)malloc(sizeof(LNode));
preNode=head;
scanf("%d",&x);
while(x!=-1)
{
newNode=(LinkList)malloc(sizeof(LNode));
newNode->data=x;
preNode->next=newNode;
preNode=newNode;
scanf("%d",&x);
}
preNode->next=NULL;
preNode=head;
head=head->next;
free(preNode);
return head;
}
//顺序打印单链表
void print_link(LinkList head)
{
LinkList h;
if(head==NULL)
return;
h=head;
while(h)
{
printf("%6d",h->data);
h=h->next;
}
printf("\n");
}
//获得单链表的长度
int get_link_length(LinkList head)
{
LinkList h;
int len=0;
if(head==NULL)
return len;
h=head;
while(h)
{
len++;
h=h->next;
}
return len;
}
//删除单链表中data值为num的结点
LinkList delete_link_node(LinkList head,int num)
{
LinkList curNode,nextNode;
if(head==NULL)
return head;
//delete the first node
curNode=head;
if(head->data==num)
{
if(head->next==NULL)
{
free(head);
head=NULL;
}
else
{
head=head->next;
free(curNode);
}
return head;
}
//delete the mid node
while(curNode->next && curNode->next->data!=num)
curNode=curNode->next;
if(curNode->next==NULL)//num is not exsite in link
return head;
nextNode=curNode->next;
curNode->next=nextNode->next;
free(nextNode);
return head;
}
//向有序单链表中插入num
LinkList insert_link_node(LinkList head, int num)
{
LinkList curNode,newNode,nextNode;
if(head==NULL)//link not exist
return head;
if(head->data>num)//插入位置为第一个结点
{
newNode=(LinkList)malloc(sizeof(LNode));
newNode->data=num;
newNode->next=head->next;
head=newNode;
return head;
}
//插入位置为中间结点或尾结点
curNode=head;
nextNode=curNode->next;
while(nextNode && nextNode->data<num)
{
curNode=nextNode;
nextNode=nextNode->next;
}
newNode=(LinkList)malloc(sizeof(LNode));
newNode->data=num;
newNode->next=nextNode;
curNode->next=newNode;
return head;
}
//逆序打印单链表
void reverse_print_link(LinkList head)
{
//static LinkList h = head;
if(head==NULL)
return;
else
{
reverse_print_link(head->next);
// if (h != head)
printf("%6d",head->data);
}
}
//逆置单链表
LinkList reverse_link(LinkList head)
{
LinkList preNode,curNode,nextNode;
preNode=head;
curNode=preNode->next;
if(head==NULL || head->next==NULL)
return head;
while(curNode)
{
nextNode=curNode->next;
curNode->next=preNode;
preNode=curNode;
curNode=nextNode;
}
head->next=NULL;
head=preNode;
return head;
}
//返回倒数第k个结点
LinkList find_Kth_toTail(LinkList head,int k)
{
LinkList pAhead,pBehind;
int i=0;
if(head==NULL || k<=0)
return NULL;
pAhead=head;
pBehind=head;
while(pAhead && i<k)
{
pAhead=pAhead->next;
i++;
}
if(pAhead==NULL && i<k)
return NULL;
if(i==k)
return head;
while(pAhead)
{
pAhead=pAhead->next;
pBehind=pBehind->next;
}
return pBehind;
}
//返回单链表的中间节点,如果是偶数个结点,返回前一个,奇数个结点,返回中间的结点
LinkList find_mid_node(LinkList head)
{
LinkList pFast,pSlow;
if(head==NULL)
return NULL;
if(head->next==NULL || head->next->next==NULL)
return head;
pFast=head;
pSlow=head;
while(pFast->next && pFast->next->next)
{
pSlow=pSlow->next;
pFast=pFast->next;
pFast=pFast->next;
}
return pSlow;
}
//合并两个有序单链表
LinkList merge_link(LinkList head1,LinkList head2)
{
LinkList h1,h2,h3,h;
if(head1==NULL && head2==NULL)
return NULL;
if(head1==NULL)
return head2;
if(head2==NULL)
return head1;
h1=head1;
h2=head2;
if(h1->data<=h2->data)
{
h3=h1;
h1=h1->next;
}
else
{
h3=h2;
h2=h2->next;
}
h=h3;
while(h1!=NULL && h2!=NULL)
{
if(h1->data<=h2->data)
{
h3->next=h1;
h3=h1;
h1=h1->next;
}
else
{
h3->next=h2;
h3=h2;
h2=h2->next;
}
}
h3->next= h1==NULL? h2 : h1;
return h;
}
//对单链表进行归并排序
LinkList merge_sort_link(LinkList head)
{
LinkList midNode,head2;
if(head==NULL)
return NULL;
if(head->next==NULL)
return head;
midNode=find_mid_node(head);
head2=midNode->next;
midNode->next=NULL;
head=merge_sort_link(head);
head2=merge_sort_link(head2);
return merge_link(head,head2);
}
LinkList create_circle_link()
{
LinkList head,newNode,preNode;
int x;
head=(LinkList)malloc(sizeof(LNode));
preNode=head;
scanf("%d",&x);
while(x!=-1)
{
newNode=(LinkList)malloc(sizeof(LNode));
newNode->data=x;
preNode->next=newNode;
preNode=newNode;
scanf("%d",&x);
}
preNode->next=head->next->next;
//preNode->next=preNode;
preNode=head;
head=head->next;
free(preNode);
return head;
}
bool is_exist_circle(LinkList head)
{
LinkList slow,fast;
slow=head;
fast=head;
if(head==NULL || head->next==NULL)
return false;
while(fast!=NULL && fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}
LinkList find_loop_port(LinkList head)
{
LinkList slow = head, fast = head;
while ( fast && fast->next )
{
slow = slow->next;
fast = fast->next->next;
if ( slow == fast ) break;
}
if (fast == NULL || fast->next == NULL)
return NULL;
slow = head;
while (slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
//判断两个单链表是否相交,如果相交返回相交点,如果不相交返回NULL
LinkList test_intersect(LinkList head1,LinkList head2)
{
bool is_loop1=false,is_loop2=false;
if(head1==NULL || head2==NULL)
return NULL;
is_loop1=is_exist_circle(head1);
is_loop2=is_exist_circle(head2);
if(is_loop1 && !is_loop2)
return NULL;
if(!is_loop1 && is_loop2)
return NULL;
if(!is_loop1 && !is_loop2)//两个链表都没有环
{
LinkList p1,p2;
int len1,len2,i;
len1=get_link_length(head1);
len2=get_link_length(head2);
p1=head1;
p2=head2;
if(len1>len2)
{
i=len1-len2;
while(i>0)
{
i--;
p1=p1->next;
}
}
else if(len1<len2)
{
i=len2-len1;
while(i>0)
{
i--;
p2=p2->next;
}
}
while(p1!=p2 && p1!=NULL && p2!=NULL)
{
p1=p1->next;
p2=p2->next;
}
if(p1==p2)
return p1;
else
return NULL;
}
if(is_loop1 && is_loop2)//两个链表都有环
{
LinkList port1,port2;
port1=find_loop_port(head1);
port2=find_loop_port(head2);
if(port1==NULL || port2==NULL)
{
printf("error\n");
return NULL;
}
if(port1==port2)//在环之前相交?
{
int len1=0,len2=0,i;
LinkList p1,p2;
p1=head1;
while(p1!=port1)
{
len1++;
p1=p1->next;
}
p2=head2;
while(p2!=port2)
{
len2++;
p2=p2->next;
}
p1=head1;
p2=head2;
if(len1>len2)
{
i=len1-len2;
while(i>0)
{
i--;
p1=p1->next;
}
}
else if(len1<len2)
{
i=len2-len1;
while(i>0)
{
i--;
p2=p2->next;
}
}
while(p1!=p2 && p1!=port1 && p2!=port2)
{
p1=p1->next;
p2=p2->next;
}
if(p1==p2)
return p1;
else
return NULL;
}
else//判断是否在环内相交
{
LinkList p;
p=port1;
port1=port1->next;
while(port1!=port2 && port1!=p)
port1=port1->next;
if(port1==port2)
return port1;
else return NULL;
}
}
}