
点击上方蓝字关注我!
如果有错误或者理解不到位的地方还请各位指正!
数据结构的相关问题,可以参考笔者写的系列数据结构文章,或者加我交流!
声明:以下内容是对清华大学出版社出版,由严蔚敏和吴伟民编著的图书《数据结构》(C语言版)的代码实现。
图书PDF版本可移步公众号【李歘歘】回复电子书领取。
上次说到了线性表的普通链表,今天我们来说一下有关静态链表,相关知识点请先自行了解。

书中位置(页码):P31-P34
函数定义及说明:
void InitSpace_SL(SLinkList &space) //创建备用列表int Malloc_SL(SLinkList &space) //提取分配空间(申请一个空闲结点)void Free_SL(SLinkList &space, int k) //释放空闲结点void CreatList_SL(SLinkList &space,int n) //创建静态链表(书上的,就是标记最后一个结点的游标为0)int LengthList_SL(SLinkList space) //获取静态链表长度void TraverseList_SL(SLinkList space) //遍历静态链表void LocateElem_SL(SLinkList space,ElemType e) //在静态链表中查找第1个值为e的元素void GetList_SL(SLinkList space,int i) //用e返回线性表中第i个元素的值void ClearList_SL(SLinkList &space) //清空链表Status ListInsert_SL(SLinkList &space,int i,ElemType e) //在L中第i个元素之前插入数据元素eStatus ListDelete_SL(SLinkList &space,int i,ElemType e) //删除L中第i个元素,并返回其值Status PriorElem_SL(SLinkList space,ElemType cur_e,ElemType pre_e) //查找前驱 cur_e不是第一个元素Status NextElem_Sq(SLinkList space,ElemType cur_e,ElemType next_e) //查找后继元素 cur_e不是最后一个元素bool EmptyList_SL(SLinkList space)//判断是否为空
程序代码:
#include<cstdio>#include<cstdlib>#define MAXSIZE 1000 //链表的最大长度#define ElemType int#define Status intusing namespace std;//静态链表的结构(数据域、游标)typedef struct {ElemType data; //数据域int cur; //游标域或者指针域}component,SLinkList[MAXSIZE];//创建备用列表void InitSpace_SL(SLinkList &space){//将一维数组space中分量链成一个备用备用链表,space[0].cur 为备用头指针//“0”表示空指针for(int i=0;i<MAXSIZE-1;i++){space[i].cur = i+1; //将每个数组分量链接到一起}//最后一个指针为0space[MAXSIZE-1].cur = 0;}//提取分配空间(申请一个空闲结点)int Malloc_SL(SLinkList &space){//若备用空间链表非空,则返回分配的结点下标,否则返回0int i = space[0].cur;if(space[0].cur)space[0].cur = space[i].cur;return i;}//释放空闲结点void Free_SL(SLinkList &space, int k){//将下标为k的空闲结点回收到备用链表space[k].cur = space[0].cur; //回收结点的“游标”指向备用链表的头结点之后节点(即第一个结点)space[0].cur = k; //备用链表的头结点指向新回收的结点}//创建静态链表(书上的,就是标记最后一个结点的游标为0)void CreatList_SL(SLinkList &space,int n){InitSpace_SL(space); //初始化备用空间int S = MAXSIZE-1;//将数组最后一个结点当做静态链表(非备用链表)的头结点int r=S; //r指向当前链表的最后结点for(int j=1;j<=n;j++){ //建立链表int i = Malloc_SL(space); //分配结点scanf("%d",&space[i].data); //输入元素值space[r].cur = i; //插入到表尾r=i; //更新表尾}space[r].cur = 0; //尾结点的指针为空printf("创建成功\n");}//获取静态链表长度int LengthList_SL(SLinkList space){int i=space[MAXSIZE-1].cur,count=0;while(i){i=space[i].cur;count++;}printf("长度为:%d\n",count);return count;}//遍历静态链表void TraverseList_SL(SLinkList space){printf("遍历链表:");int i = space[MAXSIZE-1].cur; //i指向表中的第1个结点的位序while(i) { //遍历printf("%d ",space[i].data);i = space[i].cur; //指向下一个元素}printf("\n");}//在静态链表中查找第1个值为e的元素void LocateElem_SL(SLinkList space,ElemType e){int i = space[MAXSIZE-1].cur; //i指向表中的第1个结点的位序int local = 1; //初始化其序为1while(i && (space[i].data != e)){ //当结点存在并且数据域不等于ei = space[i].cur; //指向下一个元素local++; //位序加1}if(i==0){ //如果i已经到了最后一个元素的游标(为0)则说明前面没有符合要求的元素值printf("该元素不存在\n");}else{printf("第一个值为%d的位序为:%d\n",e,local);}}//用e返回线性表中第i个元素的值void GetList_SL(SLinkList space,int i){int s=space[MAXSIZE-1].cur;int j=1;while(s && j<i){s=space[s].cur;j++;}if(s==0){ //如果i已经到了最后一个元素的游标(为0)则说明前面没有符合要求的元素值printf("位序错误\n");}else{printf("第%d个元素的值为:%d\n",i,space[s].data);}}//清空链表void ClearList_SL(SLinkList &space){int i = space[MAXSIZE-1].cur;while(i){int j = i;i = space[i].cur;Free_SL(space,j);}space[MAXSIZE-1].cur = 0;printf("清空链表成功\n");}//在L中第i个元素之前插入数据元素eStatus ListInsert_SL(SLinkList &space,int i,ElemType e){if(i<1 || i> LengthList_SL(space)+1){ //检查插入位置是否正确printf("插入位置错误\n");return 0;}int j = Malloc_SL(space); //申请新结点int k = MAXSIZE-1;if(j){ //如果结点申请成功space[j].data = e; //赋值给结点for(int l=1;l<i;l++){ //找到第i-1个结点k = space[k].cur; //指向下一个结点}space[j].cur = space[k].cur; //新结点指向第i-1个元素后的元素space[k].cur = j; //第i-1个元素指向新结点}printf("插入成功\n");return 0;}//删除L中第i个元素,并返回其值Status ListDelete_SL(SLinkList &space,int i,ElemType e){if(i<1 || i> LengthList_SL(space)){ //检查插入位置是否正确printf("删除位置错误\n");return 0;}int k = MAXSIZE-1;for(int l=1;l<i;l++){ //找到第i-1个结点k = space[k].cur; //指向下一个结点}int j = space[k].cur; //j为将删除的结点space[k].cur = space[j].cur; //将i-1结点的指针域和i+1的指针域连接起来e = space[j].data; //赋值eFree_SL(space,j);printf("删除%d个元素%d成功\n",i,e);return 0;}//查找前驱 cur_e不是第一个元素Status PriorElem_SL(SLinkList space,ElemType cur_e,ElemType pre_e){int i = space[MAXSIZE-1].cur;if(cur_e == space[i].data){printf("第一个元素没有前驱\n");return 0;}while(i && cur_e != space[i].data){pre_e = space[i].data; //将前驱结点置为当前结点i = space[i].cur; //指向下一个结点}if(i==0){printf("该元素不存在\n");}else{printf("%d的前驱是%d\n",cur_e,pre_e);}return 0;}//查找后继元素 cur_e不是最后一个元素Status NextElem_Sq(SLinkList space,ElemType cur_e,ElemType next_e){int i = space[MAXSIZE-1].cur;int j; //用j标记查找的结点while(i && cur_e != space[i].data){i = space[i].cur; //指向下一个结点}if(i==0){printf("该元素不存在\n");}else{i = space[i].cur;if(i==0){printf("最后一个元素没有后继\n");}else{next_e = space[i].data;printf("%d的后继是%d\n",cur_e,next_e);}}return 0;}//判断是否为空bool EmptyList_SL(SLinkList space){if(space[MAXSIZE-1].cur==0){ //判断其链表的头指针的游标是否为0printf("链表为空\n");return true;}else{printf("链表不为空\n");return false;}}int main(){SLinkList space;int n,a,b,d,e,f,g,h,i,j,k;printf("请输入建立链表的元素个数:\n");scanf("%d",&n); //输入链表的个数CreatList_SL(space,n);EmptyList_SL(space);LengthList_SL(space);TraverseList_SL(space);printf("请输入查找的元素值:");scanf("%d",&a); //输入查找的元素值LocateElem_SL(space,a);printf("请输入查找的位序:");scanf("%d",&b); //输入查找的位序GetList_SL(space,b);printf("请输入插入的位序和值:");scanf("%d%d",&d,&e); //输入插入的位序和值ListInsert_SL(space,d,e);TraverseList_SL(space);LengthList_SL(space);printf("请输入删除的位序:");scanf("%d",&f);ListDelete_SL(space,f,g);TraverseList_SL(space);LengthList_SL(space);printf("请输入查找的元素(返回其前驱):");scanf("%d",&h);PriorElem_SL(space,h,i);printf("请输入查找的元素(返回其后继):");scanf("%d",&j);NextElem_Sq(space,j,k);ClearList_SL(space);return 0;}————————————————版权声明:本文为CSDN博主「李歘歘」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。原文链接:https://lichuachua.blog.csdn.net/article/details/104507777
运行结果:

「往 • 期 • 精 • 选」
这些经典排序,你必须掌握
最短路径——Dijkstra算法这一篇就够了


文章转载自编程Cookbook,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





