前言
最近,自己在学习静态链表的相关知识,当然,很多人学会了单链表后,就不想去学习静态链表了,因为单链表用指针显得更加的易操作,好理解。但是指针这个名词在C语言/C++中用的非常多,但对于想java等这样的语言又怎么去运行链表呢?在这里静态链表就起到了十分重要的作用,所以学习静态链表是非常有必要的。当然,在写这篇文章之前自己还是参考过其他博主的博客,在此我想以容易理解的方式呈现这个知识给大家。
C语言编译前所需的准备
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 1000 //假设链表最长的长度为1000
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;
typedef int struct{
ElemType data;
int cur; //标,为0时表示无指向
}c,StaticLinkList[N]; //前面那c可以任意换
//定义一个输出元素的函数
int vis(int e){
printf("%d ",e);
return OK;
}
接下来,我们得初始化静态链表了。
初始化链表
Status InitList(StaticLinkList space){
int i;
for(i=0;i<N-1;i++){
space[i].cur=i+1;
}
space[N-1].cur=0;
return OK;
}
上面那一段代码的运行结果会出现下面这样:
初始化之后就得来创建一个静态链表了。
创建静态链表
//n表示链表实际长度,space为链表,一下的L也为链表,只是名字不同
Status CreateLinkList(StaticLinkList space,int n){
for(int i=1;i<=n;i++){
scanf("%d",&space[i].data);
}
space[N-1].cur=1;
space[n].cur=0;
space[0].cur=n+1;
return OK;
}
会出现这样的运行结果:
其中甲等可以是数字也可以是字符,看自己要求,我在这里以数字为主。
看到这里你应该对下面这一段代码理解了吧。
space[N-1].cur=1;
space[n].cur=0;
space[0].cur=n+1;
既然已经创建了一个链表,不妨定义一个计算链表的长度的函数。
计算长度函数的定义
//L已经存在
int ListLength(StaticLinkList L){
int j=0;
int i=L[N-1].cur; //L[N-1].cur=1,可连接上一代码理解
while(i){
i=L[i].cur;
j++;
}
return j;
}
接下来,我们得定义一个能将链表里的数据全部输出的函数。
链表的输出函数
//定义一个将静态链表每个元素全部输出的函数 ,L已经存在,n表示链表的真实长度
Status ListPrint(StaticLinkList L,int n){
int i,k;
k=N-1;
for(i=1;i<=n;i++){
k=L[k].cur;
vis(L[k].data); //上面的代码定义过这个函数
}
printf("\n");
return OK;
}
接着,我们的继续,定义一个插入元素的函数。
链表的元素的插入
设置一个备用分量
int Malloc_SSL(StaticLinkList space){
int i=space[0].cur;
if(space[0].cur){
space[0].cur=space[i].cur;
}
return i;
}
上面该段代码,我们得这样理解:
在插入元素时,我们需要一个备用的分量来存储待插入的元素,然后再进行游标的更改。
插入函数的主干代码
//表示在第i个元素前插入元素为e的数
Status ListInsert(StaticLinkList L,int i,ElemType e){
int j,k,l;
k=N-1;
if(i<1||i>ListLength(L)+1){
return ERROR;
}
j=Malloc_SSL(L); //获得空闲分量
if(j){
L[j].data=e;
for(l=1;l<=i-1;l++){
k=L[k].cur;
}
L[j].cur=L[k].cur;
L[k].cur=j;
return OK;
}
return ERROR;
}
链表元素的删除
我们知道在这里的删除并不是要删除的元素不在这个链表里了,而是在输出时跳过了它,和指针同样的道理,所以定义一个将下标为k的空闲结点回收到备用链表中。(Free函数不能在这里用)
回收空闲结点的代码
//将下标为k的空闲结点回收到备用链表
void Free_SSL(StaticLinkList space,int k){
space[k].cur=space[0].cur; //将第一个元素的cur值赋给要被删除元素的cur值
space[0].cur=k; //把要删除元素的分量赋值给第一个元素的cur值
}
删除操作的主干代码
//在实际长度为n的链表中删除第i个元素
Status ListDelete(StaticLinkList L,int i,int n){
int j,k;
if(i<1||i>ListLength(L)){
return ERROR;
}
k=N-1;
for(j=1;j<=i-1;j++){
k=L[k].cur;
}
j=L[k].cur;
L[k].cur=L[j].cur;
Free_SSL(L,j);
r eturn OK;
}
在一串串的代码支配下,不知道你是否全部理解了,同时也不知道你是否现在在哪里纠结,不过,我还有一段代码。
主函数
int main(){
StaticLinkList L;
InitList(L);
int n,i,j,e;
printf("请输入静态链表的长度: ");
scanf("%d",&n);
printf("请输入%d个元素: ",n);
CreateLinkList(L,n);
printf("打印静态链表:");
ListPrint(L,n);
printf("静态链表的长度为: %d\n",ListLength(L));
printf("请输入要删除的第几个元素: ");
scanf("%d",&i);
ListDelete(L,i,n);
printf("删除指定元素后的静态链表各元素为: ");
ListPrint(L,n-1);
printf("在第j处前插入一个指定元素,请输入j的值: ");
scanf("%d",&j);
printf("请输入要插入的元素值为: ");
scanf("%d",&e);
ListInsert(L,j,e);
printf("插入指定元素后静态链表为: ");
ListPrint(L,n);
return 0;
}
终于这个静态链表的知识也给大家介绍完了,如果你还有不了解的话,可以评论或者私信。还有,能有更好的意见,希望留言。
最后多多支持。
参考文献
《大话数据》