静态链表
什么是静态链表
静态链表是链表的一种特殊形式,其借助于数组来描述线性表的链式存储结构。
静态链表的结点:
- 数据域 data;
- 指针域 next;——指的是结点的相对地址(数组下标—游标);
静态链表的最大特点:需要预先分配一块连续的内存空间,各个结点集中安置。
静态链表VS单链表
单链表:各个结点在内存中星罗棋布,十分分散。
静态链表:需要预先分配一块连续的内存空间,各个结点集中安置。
【静态链表的解读】
- 在上图中, 0 0 0号充当头结点的角色,不存放实际元素的。
- 头结点的下一个结点是数组下标为 2 2 2的位置,存放的数据元素 e 1 e_{1} e1,这个结点也就是位序为 1 1 1的结点。
- 再往下一个结点是数组下标为 1 1 1的结点,存放的数据元素为 e 2 e_{2} e2。
- 这个游标充当“指针”;
- 游标为-1———表示已经到达表尾;
- 每个数据元素占4B,每个游标占4B(每个结点占8B)
- 因此,我们假设起始地址为 a d d r addr addr,那么 e 1 e_{1} e1的存放地址为: a d d r addr addr+8*2;
如何定义一个静态链表
#define MaxSize 10 // 静态链表的最大长度
struct Node{ //静态链表结构类型的定义
ElemType data; //存储数据元素
int next; //下一个元素的数组下标
};
void testSLinkList(){
struct NOde a[MaxSize];//数组a作为静态链表
//,,,,,,后续代码
}
//数组a有Max Size个数组元素,每个数组元素的类型都是struct Node,那么这样数组a就在内存中占用了连续的内存空间。
另外的表示
#define MaxSize 10 // 静态链表的最大长度
Typedf struct { //静态链表结构类型的定义
ElemType data; //存储数据元素
int next; //下一个元素的数组下标
}SLinkList[MaxSize];
void testSLinkList(){
SLinkList a;//a静态链表
//,,,,,,后续代码
}
————————------------------------上述代码完全等价于下面的代码——————————————
#define MaxSize 10 // 静态链表的最大长度
struct Node{ //静态链表结构类型的定义
ElemType data; //存储数据元素
int next; //下一个元素的数组下标
};
Typedf struct Node SlinkList[MaxSize];
//此处的SLinkList可以理解为:定义“一个长度大小为Max Size大小的Node型数组”
void testSLinkList(){
Struct Node a[MaxSize];
//,,,,,,后续代码
}
两个代码都合理,但是下面的代码比较合理常见。此外如果大家对Struct以及结构体之间的关系不太了解的,可以参考我之前的文章《结构体——typedf——顺序表——单链表》
《结构体——typedf——顺序表——单链表》
https://blog.csdn.net/qq_45965736/article/details/126754545
静态链表的基本操作实现
静态链表的初始化
- 要将a[0]的next设为 -1;//-1等价于NULL,开始没有其他结点;
静态链表的查找
查找某一个位序的结点——位序指的是各个结点的逻辑顺序,不同于数组下标
方法:从头结点出发挨个往后遍历结点
时间复杂度:
O
(
n
)
O(n)
O(n)
【插入位序为i的结点】
- 找到一个空的结点,存入数据元素;(为了保证空结点无脏数据,可在初始化的时候令其next值为-2代表该结点是空闲结点);
- 从头结点出发找到位序为i-1的结点;
- 修改新结点的 ∗ n e x t *next ∗next;
- 修改i-1结点的 ∗ n e x t *next ∗next;
静态链表的删除
【删除某个结点】
- 从头结点出发找到前驱结点;
- 修改前驱结点的游标;
- 被删除结点的next值设为-2;
静态链表的优缺点
优点:
增,删操作不需要移动大量元素
缺点
不能随机存取,只能从头结点开始依次往后查找;容量固定不变;
适用场景
①——不支持指针的低级语言
②——数据元素数量固定不变的场景(如操作系统的文件分配表FAT)