#include
#include
#include
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
typedef int status;
typedef int elemtype;
//创建链表
struct node
{
elemtype data;
struct node *next;
}node;
typedef struct node* linklist;
//初始化链表
status initlink(linklist *l)
{
(*l)=(linklist)malloc(sizeof(node));//(linklist)将泛型指针转换为指向节点的指针
if(!(*l))
return ERROR;//分配内存时,一定要检查是否成功分配,否则容易超内存
(*l)->next=NULL;//头节点
return OK;
}
//访问链表中的元素
status visit(elemtype c)
{
printf("%d ",c);
return OK;
}
// 返回l中元素个数
status listlength(linklist *l)
{
int count;
linklist p=(*l)->next;
while(p)
{
count++;
p=p->next;
}
return count;
}
//判断是否为空
status listempty(linklist *l)
{
linklist p=(*l)->next;
if(!p)
return TRUE;
else
return FALSE;
}
//清空l
status clearlist(linklist *l)
{
linklist p=(*l)->next,q;
while(p)
{
q=p->next;//q先记录p的后继节点,否则直接free(p)链表的后继节点将全部丢失
free(p);
p=q;//最后将后继节点赋值给p,循环往复直到表尾
}
(*l)->next=NULL;//最后记得将头节点置空
}
//用k返回链表第i个元素的值
status getelem(linklist l,int i,elemtype k)
{
int j=1;
linklist p=l->next;
while(p&&j
{
p=p->next;
j++;
}
if(!p||j>i)
return ERROR;
k=p->data;
return k;
}
//返回第一个值为k的元素的位序
status locateelem(linklist l,elemtype k)
{
linklist p=l->next;
int i=1;
while(p)
{
if(p->data==k)
return i;
i++;
p=p->next;
}
if(!p)
return ERROR;
}
// 在链表的第i个位置插入元素k
status listinsert(linklist *l,int i,elemtype k)
{
linklist p=*l,q;
int j=1;
while(p&&j
{
j++;
p=p->next;
}
if(!p||j>i)
return ERROR;
q=(linklist)malloc(sizeof(node));
q->data=k;
q->next=p->next;
p->next=q;
return OK;
}
//删除链表中第i个位置的元素,并用k返回
status deleteelem(linklist *l,int i,elemtype *k)
{
int j=1;
linklist p=*l,q;
while(p->next&&j
{
p=p->next;
j++;
}
if(!(p->next)||j>i)
return ERROR;
q=p->next;
p->next=q->next;
*k=q->data;
free(q);//一定要释放掉
return OK;
}
//依次输出链表中的各个元素
status traverselist(linklist l)
{
linklist p=l->next;
while(p)
{
visit(p->data);
p=p->next;
}
printf("\n");
return OK;
}
//随机产生n个元素的值,建立带表头结点的单链表(头插法)
status createlisthead(linklist *l,int n)
{
int i;
linklist p=*l,q;
p->next=NULL;//建立一个头节点,使得在表头插入操作和在表中间插入的方法相同
srand(time(0));
for(i=0;i
{
q=(linklist)malloc(sizeof(node));
q->data=rand()%100;
q->next=p->next;
p->next=q;
q=q->next;//切记写q=q->next
}
return OK;
}
// 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法)
void createlisttail(linklist *l,int n)
{
int i;
linklist p=*l,q;//p实际上记录的是尾节点
srand(time(0));
for(i=0;i
{
q=(linklist)malloc(sizeof(node));
q->data=rand()%100;
p->next=q;
p=q;//让p等于新的尾节点
}
p->next=NULL;//插入之后一定要把表尾置空,否则会引发错误
}
//链表的逆序输出
status inverselist(linklist l)
{
linklist current,pnext,prev;
current=l->next;//current的初始位置为头节点
pnext=current->next;
current->next=NULL;//将头节点从链表上取下指向NULL
while(pnext)
{
prev=pnext->next;//prev记录pnext后继节点,之后要使pnext指向current,为防止断链,将onext的后继节点提前加以记录
pnext->next=current;
current=pnext;//current向后移动
pnext=prev;//pnext向后移动
}
l->next=current;//将链表头节点指向current
return OK;
}
//逆序链表的原理其实就是将指针反向,再将头节点置为原先的最后一个节点
//找到链表中心节点
status getmidnode(linklist l,elemtype *e)
{
linklist search,mid;
search=mid=l;
while(search->next)//快慢指针法的循环条件是search->next,防止越过尾节点造成错误
{
if(search->next->next)
{
search=search->next->next;
mid=mid->next;
}
else
search=search->next;//如果只有一个节点的情况
}
*e=mid->data;
return OK;
}
//删除重复节点
status deletesamenode(linklist l,elemtype *e)
{
linklist p=l->next,q,r;
while(p)
{
q=p;//将p赋给q让q移动以遍历链表
while(q->next)
{
if(p->data==q->next->data)
{
r=q->next;
*e=r->data;
q->next=r->next;
free(r);
printf("找到重复元素为%d\n",*e);
}
else
q=q->next;
}
p=p->next;
}
return OK;
}
//链表的冒泡排序(内容交换)
status bubblesort(linklist l)
{
int swapped,temp;
linklist p=l->next,n;
do
{
swapped=0;
for(p=l->next;p->next;p=p->next)
{
if(p->data>p->next->data)
{
temp=p->data;
p->data=p->next->data;
p->next->data=temp;
swapped=1;
}
}
}
while(swapped);
return OK;
}
//冒泡排序(指针交换版)
status bubblesortbyptr(linklist l)
{
int swapped;
linklist head=l->next,pnext,temp;
do
{
swapped=0;
for(head=l->next;head->next;head=head->next)
{
if((head->data)>(head->next->data))
{
temp=head;
head=head->next;
head->next=temp;
swapped=1;
}
}
}
while(swapped);
return OK;
}
//链表的选择排序
status selectsort(linklist l)
{
linklist p,q,min,temp;
for(p=l->next;p->next;p=p->next)
{
min=p;
for(q=p->next;q->next;q=q->next)
{
if(q->datadata)
min=q;
}
if(min!=p)
{
temp=min;
q=p;
p=temp;
}
}
return OK;
}
int main(void)
{
linklist l;
initlink(&l);
int i;
printf("初始化l后,l.length=%d\n",listlength(&l));
for(i=1;i<=5;i++)
listinsert(&l,1,i);
printf("在l的表头插入1~5后,l.data=");
traverselist(l);
printf("\n");
printf("listlength=%d\n",listlength(&l));
i=listempty(&l);
printf("L是否空:i=%d(1:是 0:否)\n",i);
clearlist(&l);
i=listempty(&l);
printf("清空L后:ListLength(L)=%d\n",listlength(&l));
printf("L是否空:i=%d(1:是 0:否)\n",i);
for(i=1;i<=10;i++)
{
listinsert(&l,i,i);
}
printf("在L的表尾依次插入1~10后:L.data=");
traverselist(l);
printf("listlength=%d\n",listlength(&l));
listinsert(&l,1,0);
printf("在L的表头插入0后:L.data=");
traverselist(l);
printf("listlength=%d\n",listlength(&l));
for(i=5;i>=4;i--)
{
int k;
printf("第%d个元素的值为%d\n",i,getelem(l,i,k));
}
for(i=2;i>=1;i--)
{
int k,j;
j=deleteelem(&l,i,&k);
if(j==ERROR)
printf("删除第%d个元素失败\n",i);
else
printf("删除第%d个元素的值为%d\n",i,k);
}
int j=locateelem(l,5);
printf("第一个值为5的元素位序为%d\n",j);
printf("依次输出l的元素");
traverselist(l);
printf("\n");
clearlist(&l);
j=listlength(&l);
printf("清空后,l.length=%d\n",j);
createlisthead(&l,20);
printf("整体创建l的元素(头插法)");
traverselist(l);
createlisttail(&l,20);
printf("整体创建l的元素(尾插法)");
traverselist(l);
printf("逆序输出链表:");
inverselist(l);
traverselist(l);
elemtype e;
getmidnode(l,&e);
printf("找到中间结点为:%d\n",e);
deletesamenode(l,&e);
printf("删除重复元素后的链表为:");
traverselist(l);
printf("对链表进行冒泡排序:");
bubblesort(l);
traverselist(l);
printf("对链表进行交换指针的冒泡排序:");
bubblesortbyptr(l);
traverselist(l);
printf("对链表进行选择排序:");
selectsort(l);
traverselist(l);
system("pause");
}