线性表链式存储-使用c语言实现,线性表链式存储的C语言实现(含源码)

#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");

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值