#include <stdio.h>
#include <stdlib.h>
typedef struct Lnode
{
int data;
struct Lnode *next;
}Lnode;
//头插法实现单链表
Lnode* createLinkListByHead(int a[],int n)
{
Lnode* head=(Lnode*)malloc(sizeof(Lnode));
head->next=NULL;
int i=0;
for(i=0;i<n;i++)
{
Lnode* node=(Lnode*)malloc(sizeof(Lnode));
node->data=a[i];
node->next=head->next;
head->next=node;
}
return head;
}
//尾插法实现单链表
Lnode* createLinkListByTail(int a[],int n)
{
Lnode *head=(Lnode*)malloc(sizeof(Lnode));
head->next=NULL;
int i=0;
Lnode *p=head;
for(i=0;i<n;i++)
{
Lnode* node=(Lnode*)malloc(sizeof(Lnode));
node->data=a[i];
p->next=node;
p=node;
}
p->next=NULL;
return head;
}
//初步实现
Lnode* swapLinklist(Lnode *head)
{
if(head==NULL || head->next==NULL)
return head;
Lnode *p=head;
Lnode *pp=head->next;
Lnode *pNext=NULL;
Lnode *pre=NULL;
while(pp!=NULL)
{
p->next=pp;
pNext=pp->next;
pp->next=pre;
pre=pp;
pp=pNext;
}
return p;
}
//上面方法的简单优化
Lnode* swapListLink(Lnode *head)
{
if(head==NULL || head->next==NULL)
{
return head;
}
Lnode *p=head->next;
Lnode *pNext=NULL;
Lnode *pre=NULL;
while(p!=NULL)
{
head->next=p;
pNext=p->next;
p->next=pre;
pre=p;
p=pNext;
}
return head;
}
//进一步优化
Lnode* swapList(Lnode *head)
{
if(head==NULL || head->next==NULL)
return head;
Lnode *p=head->next;
Lnode *pNext=NULL;
head->next=NULL;
while(p!=NULL)
{
pNext=p->next;
p->next=head->next;
head->next=p;
p=pNext;
}
return head;
}
//链表k翻转,还有一种更方便的方法,就是遍历一遍把值保存在一个数组里面
//根据规则重新给链表赋值
void swapListByK(Lnode *head,int k)
{
if(head==NULL || head->next==NULL)
{
return;
}
int i=0;
Lnode *p=head->next;
head->next=NULL;
Lnode *pTail=head,*pHead=NULL,*pNext=NULL;
while(p!=NULL)
{
if(i%k==0)
{
pHead=pTail;
pTail=p;
}
pNext=p->next;
p->next=pHead->next;
pHead->next=p;
p=pNext;
i++;
}
}
//假设两个单链表都没有环
int isCrossed(Lnode *p,Lnode *q)
{
Lnode *pp=p,*qq=q;
while(pp->next!=NULL)//注意pp->next!=null和pp!=null的区别,两种情况最后的点是不同的
pp=pp->next;
while(qq->next!=NULL)
qq=qq->next;
if(pp==qq)
return 1;
return 0;
}
//判断一个单链表是否自身有环
int isHaveCircle(Lnode *p)
{
if(NULL==p || NULL==p->next)
return 0;
Lnode *low,*fast;
low=p,fast=p;
while(NULL!=fast && NULL!=fast->next)//条件判定的前后顺序很重要
{
low=low->next;
fast=fast->next->next;
if(low==fast)
return 1;
}
return 0;
}
//可能有cycle(但是两个都有单独的环会无限循环)
int isTwoCrossed(Lnode *p,Lnode *q)
{
if(!isHaveCircle(p) && !isHaveCircle(q))
return isCrossed(p,q);
if(!isHaveCircle(p) || !isHaveCircle(q))
return 1;
Lnode *pp=p,*qq=q;
while(pp!=NULL && qq!=NULL && pp!=qq)
{
pp=pp->next;
if(qq->next!=NULL)
qq=qq->next->next;
else
qq=qq->next;
}
if(qq==pp && qq!=NULL)
return 1;
return 0;
}
int main()
{
int a[6]={1,2,3,4,5,6};
Lnode *head=createLinkListByHead(a,6);
Lnode *resultBeforeSwap=head->next;
while(resultBeforeSwap!=NULL)
{
printf("%3d",resultBeforeSwap->data);
resultBeforeSwap=resultBeforeSwap->next;
}
printf("\n");
swapList(head);
Lnode* result=head->next;
while(result!=NULL)
{
printf("%3d",result->data);
result=result->next;
}
printf("\n");
swapListByK(head,3);
Lnode* result2=head->next;
while(result2!=NULL)
{
printf("%3d",result2->data);
result2=result2->next;
}
return 0;
}
还有链表的各种排序补充。。。
以上是单链表常见的操作,抛砖引玉,未完待续。。。