线性表的链式存储结构

顺序表插入、删除时需要通过移动数据来实现,影响了执行效率。

而链表不要求逻辑上相邻的两个数据元素物理上也相邻,因此对线性表的插入、删除不需要移动数据元素,只需要修改链。

下面介绍带头结点的链式表:

数据结构:

typedef int ElementType;
typedef struct LNode * PtrToLNode;
struct LNode{
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;//这里的位置是结点的地址
typedef PtrToLNode List;
1.初始化:

//初始化
List MakeEmpty(){
List L;
L = (List)malloc(sizeof (struct LNode));
if (!L)
exit (-1);
L->Next = NULL;
return L;
}
2.求表长

在顺序存储表示的线性表中求表长是一件很容易的事,直接返回Last+1值就可以了,但是在链式存储表示中,需要将链表从头到尾遍历一遍;设一个移动的指针p和计数器cnt,初始化后,p从表的第一个结点开始往后移,同时计数器cnt+1.

//求表长
int Length(List L){
Position p;
int cnt = 0;
p = L->Next;
while§{
p = p -> Next;
cnt++;
}
return cnt;
}
3.查找(按序号查找FindKth)

对于顺序存储,按序号查找是很直接的事,要得到第k个元素的值,直接取L->Data[k-1]就可以了。而对于链式表就需要采用求表长的思路,从头遍历,判断当前结点是否是第K个,若是,返回该结点的值,否则继续后一个。

//根据指定的位序查找s
int FindKth(List L,int K){
Position p;
int cnt = 1;//位序从1开始
p = L->Next;
while(p&&cnt<K){
p = p-> Next;
cnt++;
}
if((cnt==K)&&p) printf(“您查找的数为:%d\n”,p -> Data);
else printf(“您查找数不存在”);
}
4.查找(按值查找Find)

按值查找的方法也是从头到尾遍历,直到找到为止

//按值查找
Position Find(List L,int X){
Position p;
p = L->Next;
while(p&&p->Data!=X){
p = p-> Next;
}
if§ printf(“查找成功,您查找的数为:%d\n”,p->Data);
else printf(“您查找数不存在”);
}
5.插入

带头结点的链式表的插入

//插入
List Insert(List L ,ElementType X,int i){
Position tmp,pre;
int cnt =0 ;
pre = L;
while(pre&&cnt<i-1){
pre = pre->Next;
cnt++;
}
if(pre==NULL||cnt!=i-1){
printf(“插入位置参数错误\n”);
}
else{
tmp = (Position)malloc(sizeof(struct LNode));
tmp->Data=X;
tmp->Next=pre->Next;
pre->Next=tmp;
}

}
6.删除

删除指定位序i的元素,首先需要找到被删除结点的前一个元素,然后再删除结点并释放空间。

//删除
bool Delete(List L,int i){
Position tmp,pre;
int cnt = 0;
pre = L;
while(pre&&cnt<i-1){
pre=pre->Next;
cnt++;
}
if(preNULL||cnt!=i-1||pre->NextNULL){
printf(“删除位置参数错误”);
}
else{
tmp = pre->Next;
pre->Next = tmp->Next;
free(tmp);
printf(“删除成功”);
}
}
7.遍历链表并输出

void DisLinkList(List L)
{
List p = L->Next;
printf("输出链表: “);
while §
{
printf(”%d ", p->Data);
p = p->Next;
}
}
完整的程序代码:
#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct LNode * PtrToLNode;
struct LNode{
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;//这里的位置是结点的地址
typedef PtrToLNode List;
//初始化
List MakeEmpty(){
List L;
L = (List)malloc(sizeof (struct LNode));
if (!L)
exit (-1);
L->Next = NULL;
return L;
}

//根据指定的位序查找
int FindKth(List L,int K){
Position p;
int cnt = 1;//位序从1开始
p = L->Next;
while(p&&cnt<K){
p = p-> Next;
cnt++;
}
if((cnt==K)&&p) printf(“您查找的数为:%d\n”,p -> Data);
else printf(“您查找数不存在”);
}

//按值查找
Position Find(List L,int X){
Position p;
p = L->Next;
while(p&&p->Data!=X){
p = p-> Next;
}
if§ printf(“查找成功,您查找的数为:%d\n”,p->Data);
else printf(“您查找数不存在”);
}

//插入
List Insert(List L ,ElementType X,int i){
Position tmp,pre;
int cnt =0 ;
pre = L;
while(pre&&cnt<i-1){
pre = pre->Next;
cnt++;
}
if(pre==NULL||cnt!=i-1){
printf(“插入位置参数错误\n”);
}
else{
tmp = (Position)malloc(sizeof(struct LNode));
tmp->Data=X;
tmp->Next=pre->Next;
pre->Next=tmp;
}

}

//删除
bool Delete(List L,int i){
Position tmp,pre;
int cnt = 0;
pre = L;
while(pre&&cnt<i-1){
pre=pre->Next;
cnt++;
}
if(preNULL||cnt!=i-1||pre->NextNULL){
printf(“删除位置参数错误”);
}
else{
tmp = pre->Next;
pre->Next = tmp->Next;
free(tmp);
printf(“删除成功”);
}
}

//求表长
int Length(List L){
Position p;
int cnt = 0;
p = L->Next;
while§{
p = p -> Next;
cnt++;
}
return cnt;
}

void DisLinkList(List L)
{
List p = L->Next;
printf("输出链表: “);
while §
{
printf(”%d ", p->Data);
p = p->Next;
}
}

int main(){
Position pre;
Position L = MakeEmpty();
pre = L;
int i,n,x,len,cz,del;
//插入
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&x);
Insert(pre,x,i);
}
//输出
DisLinkList(pre);
printf("\n");
//求表长
len = Length(L);
printf(“表长为:%d”,len);
printf("\n");
//按值查找
printf(“请输入你要按值查找的数:\n”);
scanf("%d",&cz);
Find(L,cz);
printf("\n");
//按序号查找
printf(“请输入你要按序号查找的数的序号:\n”);
scanf("%d",&cz);
FindKth(L,cz);
printf("\n");
//删除
printf(“请输入你要删除的数的下标:\n”,del);
scanf("%d",&del);
Delete(L,del);
DisLinkList(pre);
printf("\n");
return 0;
}
运行结果:


作者:玥娃娃
来源:CSDN
原文:https://blog.csdn.net/qq_41815146/article/details/81569532
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值