静态链表详解(C语言版)

静态链表详解(C语言版)你认识静态链表吗 听起来是不是很陌生呢 本文将较为详细的向你介绍它 感兴趣的话就一起来看看吧


前言

        你认识静态链表吗?听起来是不是很陌生呢?本文将较为详细的向你介绍它,感兴趣的话就一起来看看吧。

一、静态链表的定义

        逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成的链表称为静态链表。也就是说静态链表是用数组来实现链式存储结构,目的是方便在不设指针类型的高级程序设计语言中使用链式结构。它的优点是和动态链表一样,删除和插入元素时间复杂度低;不足是和数组一样,需要提前分配一块较大的空间。

二、静态链表的设计

1、结构描述
在这里插入图片描述
        使用结构体数组来构造静态链表,结构体数组内的每一个元素充当静态链表的结点。每个结点都包含数据域与游标这两部分,数据域用来存放数据、游标用来指示该结点的下一个结点对应的数组下标。有了这样的一个结构那么我们要如何来对静态链表进行管理呢?静态链表的管理分为对已申请结点的管理和对未申请结点的管理。




        首先来谈谈如何来对已申请结点进行管理,将静态链表0位置的结点设置为头结点head,用它来对已申请的结点进行管理。该结点的特点是数据域不存数据,游标为第一个申请结点所对应的下标(如果该静态链表还未申请结点来存放数据,那么该值为-1表示该静态链表为空。),这样一来就可将各个结点像动态链表结点一样组织连接起来进行管理。

        了解了对已申请结点的管理方法之后,我们再来谈谈对未申请结点的管理。未申请的结点也就是待分配的结点,对它们的管理方式可以模仿对已申请结点的管理方式。我们可以将静态链表1位置的结点设置为备用区的头结点pool,它的数据域不存放数据,它的游标值是第一个未申请结点对应的下标(如果该结点之后不存在未申请的结点,那么游标值为0表示该结点之后不存在未申请的结点),这样一来也就可以将各个未申请的结点像动态链表结点一样组织连接起来进行管理。

2、代码描述

        这里将静态链表的最大空间设置成20个结点(未申请结点+已申请结点),读者可根据需求更改静态链表的最大空间。

#define MAX_SIZE 20 #define ElemType char typedef struct ListNode { 
     ElemType data; int cur; //静态链表中的游标 }ListNode; //静态链表实际上就是一个结构体数组 typedef ListNode StaticList[MAX_SIZE]; 

三、静态链表的操作

1.初始化

//初始化 void InitSList(StaticList &space) { 
     //初始化备用空间pool(即下标1~MAX_SIZE-1),其中下标为1的空间是备用空间的头结点,用于指向可使用的备用空间 for(int i=1; i<MAX_SIZE-1; ++i) { 
     //备用区每个空间的游标指向下一个空间 space[i].cur = i+1; } //备用区的最后一个空间,后无可以空间,游标为0 space[MAX_SIZE-1].cur = 0; //初始化时为空的静态链表,无数据结点,头结点的游标为-1 space[0].cur = -1; } 

2、结点数据显示

//显示静态链表中的数据 void ShowSList(StaticList &space) { 
     int i = space[0].cur;//从第一个数据结点开始搜索 while(i != -1)//将所有的数据结点打印 { 
     printf("%c-->",space[i].data); i = space[i].cur; // p = p->next; } printf("Nul.\n"); } 

3、结点申请

//申请静态链表结点 int Malloc_SL(StaticList &space) { 
     int i = space[1].cur; //如果备用区中还有可用空间那么就进行分配(更改备用区头指针的指向) if(space[1].cur != 0) space[1].cur = space[i].cur; return i; } 

4、头插

//静态链表的头插 void Insert(StaticList &space, ElemType x) { 
     int i = Malloc_SL(space);//申请空间 if(i == 0)//如果为零表示申请空间失败 { 
     printf("申请节点空间失败.\n"); return; } space[i].data = x; //如果之前静态链表中无数据结点,需要更改头结点的指向 if(space[0].cur == -1) { 
     space[i].cur = -1; //space[0].cur = i; } else //如果之前已经有数据结点那么直接头插 { 
     space[i].cur = space[0].cur; } space[0].cur = i; } 

5、释放结点(空间回收)

//回收空间 void Free_SL(StaticList &space, int k) { 
     //将要回收的空间重新加入到备用空间 space[k].cur = space[1].cur; space[1].cur = k; } 

6、头删

//静态链表的头删 void Delete(StaticList &space) { 
     //删除结点 int i = space[0].cur; space[0].cur = space[i].cur; //释放删除结点的空间 Free_SL(space,i); } 

总结

        静态链表综合了顺序表和动态链表的优点:使用数组存储数据元素,便于做查找遍历操作;同时,在数组中借鉴了动态链表的特点,在链表中插入或者删除结点时只需更改相关结点的游标,不需要移动大量元素。

附录

下面给出静态链表测试源码

Main.cpp

#include"StaticList.h" void main() { 
     StaticList SL; //建立静态链表 InitSList(SL); //初始化静态链表 for(int i=0; i<5; ++i) { 
     Insert(SL,'A'+i);//头插 } //显示静态链表的数据 ShowSList(SL); Delete(SL);//头删 ShowSList(SL); } 

StaticList.h

#ifndef __STATICLIST_H__ #define __STATICLIST_H__ #include 
      #define MAX_SIZE 20 #define ElemType char typedef struct ListNode { 
     ElemType data; int cur; //静态链表中的游标 }ListNode; //静态链表实际上就是一个结构体数组 typedef ListNode StaticList[MAX_SIZE]; int Malloc_SL(StaticList &space); void Free_SL(StaticList &sapce,int k); void InitSList(StaticList &space); void Insert(StaticList &space, ElemType x); void Delete(StaticList &space); void ShowSList(StaticList &space); #endif //__STATICLIST_H__ 

StaticList.cpp

#include"StaticList.h" //申请静态链表结点 int Malloc_SL(StaticList &space) { 
     int i = space[1].cur; //如果备用区中还有可用空间那么就进行分配(更改备用区头指针的指向) if(space[1].cur != 0) space[1].cur = space[i].cur; return i; } //回收空间 void Free_SL(StaticList &space, int k) { 
     //将要回收的空间重新加入到备用空间 space[k].cur = space[1].cur; space[1].cur = k; } //初始化 void InitSList(StaticList &space) { 
     //初始化备用空间pool(即下标1~MAX_SIZE-1),其中下标为1的空间是备用空间的头结点,用于指向可使用的备用空间 for(int i=1; i<MAX_SIZE-1; ++i) { 
     //备用区每个空间的游标指向下一个空间 space[i].cur = i+1; } //备用区的最后一个空间,后无可以空间,游标为0 space[MAX_SIZE-1].cur = 0; //初始化时为空的静态链表,无数据结点,头结点的游标为-1 space[0].cur = -1; } //静态链表的头插 void Insert(StaticList &space, ElemType x) { 
     int i = Malloc_SL(space);//申请空间 if(i == 0)//如果为零表示申请空间失败 { 
     printf("申请节点空间失败.\n"); return; } space[i].data = x; //如果之前静态链表中无数据结点,需要更改头结点的指向 if(space[0].cur == -1) { 
     space[i].cur = -1; //space[0].cur = i; } else //如果之前已经有数据结点那么直接头插 { 
     space[i].cur = space[0].cur; } space[0].cur = i; } //显示静态链表中的数据 void ShowSList(StaticList &space) { 
     int i = space[0].cur;//从第一个数据结点开始搜索 while(i != -1)//将所有的数据结点打印 { 
     printf("%c-->",space[i].data); i = space[i].cur; // p = p->next; } printf("Nul.\n"); } //静态链表的头删 void Delete(StaticList &space) { 
     //删除结点 int i = space[0].cur; space[0].cur = space[i].cur; //释放删除结点的空间 Free_SL(space,i); } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201983.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:09
下一篇 2026年3月20日 上午8:09


相关推荐

  • 智能小区管理系统_php导航网源码

    智能小区管理系统_php导航网源码☞文末有福利哟,请关注小枣获取方案智慧小区智慧物业管理系统一体化解决方案传统物业在管理上不仅成本高,服务质量也很难有所保障。现在很多小区都安装了智能物业管理系统,它将信息手段与现代物业管理工作相结合,帮助物业管理团队及时响应客户需求,降低运营成本,提升服务品质。智慧物业是指充分利用物联网、云计算、移动互联网等新一代信息技术的集成应用,将物业各个单位紧密连接起来,实现数据的融合,建立起高效…

    2022年10月8日
    4
  • 前端性能优化之“离线缓存manifest”

    前端性能优化之“离线缓存manifest”在本专栏的这一篇文章中 给各位引出了一个 不同寻常的 性能体验优化方式 离线缓存 并介绍了它的简单用法 本文来详细说说 啥是离线缓存离线缓存又叫 ApplicationC 是从浏览器缓存中分出来一块缓存区 用来存储一定的资源 它是 HTML5 的新特性 你可以使用它将构成 web 应用程序的资源 如 HTML css JavaScript 图片等存储到本地缓存中 这样不仅可以使以后进来时更加方便 还可以在离线状态时 无差别 继续使用 web 应用 离线缓存和普通的浏览器网页缓存有明显的区别

    2026年3月18日
    2
  • 【网络教程】群晖修改 sn 和 MAC,生成器,cpolar内网穿透[通俗易懂]

    【网络教程】群晖修改 sn 和 MAC,生成器,cpolar内网穿透[通俗易懂]参考文章1参考文章2更多

    2022年5月7日
    227
  • oracle启动时必须启动哪两个服务_富士康的领导

    oracle启动时必须启动哪两个服务_富士康的领导七个服务的含义分别为:1.OracleORCLVSSWriterService:Oracle卷映射拷贝写入服务,VSS(VolumeShadowCopyService)能够让存储基础设备(比如磁盘,阵列等)创建高保真的时间点映像,即映射拷贝(shadowcopy)。它可以在多卷或者单个卷上创建映射拷贝,同时不会影响到系统的系统能。(非必须启动)2.OracleDBConsole…

    2025年5月26日
    4
  • SDL_Delay函数

    SDL_Delay函数用此函数来暂停指定的时间,单位为ms。voidSDL_Delay(Uint32ms)参考文章:http://blog.csdn.net/vagrxie/article/details/5735979http://www.cppblog.com/lf426/archive/2008/04/28/48325.html蔡军生C++培训

    2022年5月5日
    43
  • c语言strstr的使用及模拟实现strstr函数[通俗易懂]

    c语言strstr的使用及模拟实现strstr函数[通俗易懂]c语言strstr的使用及模拟实现strstr函数

    2022年10月10日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号