链表线性表及其操作c语言代码大全,对线性表理解以及C语言实现链表的插入删除等操作。...

我们首先用一个结构体定义链表的储存结构,代码如下。

#include

#include

typedef int ElemType;

/*-------------线性表的链式储存结构-----------------*/

typedef struct LNode{

ElemType data;

struct LNode *next;

}LNode,*LinkList;

typedef int Status;

在链表L中第i个元素之前插入一个新的元素:我们需要找到第i-1个结点,然后修改其指向后继的指针。假设新插入的元素e,新生成的结点为s,我们可以分为三个个步骤:1.让e的后继指向i-1的后继(也就是指向i),2.让i-1的后继的指针指向s,3.然后讲新插入的元素值赋给新插入结点的数据域。这样便插入了一个新的元素。代码如下:

Status ListInsert_L(LinkList *L,int i,ElemType e)/*在L中第i个元素之前插入新的元素e*/

{

LinkList p,s;

int j=0;

p=*L;

while(p&&j

{

p=p->next;

++j;

}

if(!p||(j>i-1))return 0;/*i小于1或者大于表长加1*/

s=(LinkList)malloc(sizeof(LNode));/*生成新的节点*/

s->next=p->next;p->next=s;/*插入到L中*/

s->data=e;

return 1;

}

要想在链表L中删除第i个元素与插入元素的思路相同,找到第i-1个结点,然后修改其后继的指针。假设删除第i个结点,一个中间变量。1.我们首先找到第i-1个结点;2.q=p->next,p->next=q->next;这样i-1结点的后继指针便指向了i+1结点,我们可以然后删除q,便删除了第i个结点。代码如下:

Status ListDelete_L(LinkList *L,int i)/*删除L中第i个数据元素*/

{

LinkList p,q;

int j;

p=*L;j=0;

while(p->next&&j

{

p=p->next;++j;

}

if(!p->next||(j>i-1))return 0;/*删除位置不合理*/

q=p->next;p->next=q->next;/*删除并释放结点*/

free(q);

return 1;

}

取出链表L中第i个元素的值:因为单链表是一种顺序储存结构,因此如果想要找到第i个元素首先需要找到第i-1个元素,

6d71eb7c692ddfb61fcd7af6ea3f3e10.png

基本操作为移动指针,比较j和i,指针p始终指向链表中的第j个元素。代码如下:

Status GetElem_L(LinkList L,int i,ElemType *e)/*取出链表L中第i个元素的值*/

{

LinkList p;int j;

p=L;j=0;

while(p&&j

{

p=p->next;++j;

}

if(!p||j>i)return 0;

*e=p->data;  /*用来返回第i个结点的值*/

return 1;

}

查询链表L中与e元素相同的第一次出现的位序:我们可以遍历整个链表,找到元素后返回位序,并停止遍历;代码如下:

Status LocateElem_L(LinkList *L,ElemType e,int *n/*,compare()*/)/*查询链表中与e相同元素的第一个值*/

{                                                                /*并用n返回其位置*/

LinkList p;

int j=0;

p=*L;

while(p)/*判断p是否为空*/

{

p=p->next;++j;

if(p->data==e)/*判断p所指向的数据的值是否与e相等*/

{

*n=j;return 1;

break;

}

}

return 0;

}

逆序插入法生成一个链表:和插入思想相同,生成头结点函数写在了主函数(测试函数与)中,最后会有说明。代码如下:

void CreateList_L(LinkList *L,int n)/*逆序输入n个元素的值,n为链表元素的个数*/

{

LinkList p,s;

p=*L;

for(n;n>0;--n)

{

int tmp;

s=(LinkList)malloc(sizeof(LNode));/*生成新的结点*/

scanf("%d",&tmp);

s->data=tmp;     /*插入元素的值*/

s->next=p->next;p->next=s;  /*插入到表头*/

}

}

输出链表所有的值:遍历链表所有元素并依次输出。代码如下:

Status ListTraverse(LinkList *L)/*用于输出链表的所有值*/

{

LinkList p;

p=*L;

p=p->next;/*让p指向第一个结点*/

while(p)/*判断p是否为空*/

{

printf("%d\t",p->data);/*输出元素的值,并让p指向下一个结点*/

p=p->next;

}

printf("\n");

return 0;

}

测试链表的长度:代码如下:

Status ListLenght_L(LinkList *L)/*用于测链表的长度*/

{

int j=0;

LinkList p=*L;

while(p)/*判断p是否为空*/

{

j++;

p=p->next;

}

return j;

}

接下来我们测试一下程序的运行结果,在测试程序中生成的链表元素个数为5,结点的个数(包含头结点)为6。1.输入的数据为11,12,13,14,15;2.逆序生成链表输出;3.在第四个元素之前插入“8”然后输出;4.删除第四个元素在输出;5.取出第二个元素的值;6.链表的长度;7.返回元素"11"的位序。代码如下:

void main()/*测试函数*/

{

int n,n1,ex;/*用n表示取出元素的值,n1表示测试链表的长度,ex表示第一个与元素e相等的位置*/

LinkList L=(LinkList)malloc(sizeof(LNode));

L->next=NULL;

printf("请输入5个元素,用来逆序生成链表:");

CreateList_L(&L,5);/*我们设置为5个元素*/

printf("生成的链表为:");

ListTraverse(&L);

ListInsert_L(&L,4,8);

printf("在第四个元素前面插入元素8:生成的链表为:");

ListTraverse(&L);

ListDelete_L(&L,4);/*删除第四个结点*/

printf("删除第四个元素生成的链表为:");

ListTraverse(&L);

GetElem_L(L,2,&n);/*取出第二个元素的值*/

printf("第二个元素的值为:%d\n",n);

n1=ListLenght_L(&L);/*用来求链表的长度*/

printf("链表的长度为:%d\n",n1);

if( LocateElem_L(&L,11,&ex))/*查找与元素11相同的位序*/

{

printf("与元素11相同的元素的位序为:%d\n",ex);

}

else

{

printf("与元素11相同的元素的位序为:查找失败");

}

system("pause");

}

运行结果如下:

ebadee02706d3e76f9a570134d22ee4d.png

总结:

优点:1.它是一种动态储存结构,整个储存空间供多链表共用;2.使用时不用预先分配空间;3.插入删除方便;

缺点:1.指针占用额外储存空间,;2.不能随机存取,查找速度慢;

-------------------------------------------------------------------------华丽分割线-----------------------------------------------------

学习数据结构链表后记录,有错误的欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值