数据结构——静态链表(c语言笔记) - 实践

1.什么是静态链表

静态链表(StaticList)就是用一个数组来模拟链表,每个元素是一个“节点”,里面有两部分:

data —— 存放数据

cur —— 存放“下一个节点”的数组下标(就像 next 指针)

额外规则:

下标 0 专门用来存储“链表头指针”。

下标 1 开始 是“备用链表”(空闲结点池)。

cur == -1 表示“没有下一个结点”(就像指针版的 NULL)。

cur == 0 用来表示备用链表已经空了,不能再分配。

2.静态链表代码与过程详解

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

InitSList —— 初始化
void InitSList(StaticList& space)
{
for (int i = 1; i < MAX_SIZE - 1; ++i)
{
space[i].cur = i + 1;  // 让 1→2→3→... 串成一条备用链表
}
space[MAX_SIZE - 1].cur = 0;  // 最后一个指向 0,表示备用链表结束
space[0].cur = -1;            // 真正的链表是空的
}

举例:假设 MAX_SIZE = 6,初始化后数组状态如下:

下标datacur说明
0?-1表示链表为空
12空闲链表第1个结点,指向2
23空闲链表结点,指向3
34指向4
45指向5
50空闲链表结束

此时:

空闲链表 = 1→2→3→4→5→0

真实链表 = 空

Malloc_SL —— 分配结点
int Malloc_SL(StaticList& space)
{
int i = space[1].cur;          // 拿到备用链表的第一个
if (space[1].cur != 0)
space[1].cur = space[i].cur;  // 更新备用链表头
return i;  // 返回可用结点下标
}

举例:

当前空闲链表是 1→2→3→4→5→0

调用 Malloc_SL(space):

i = space[1].cur = 2,分配到下标 2。

更新 space[1].cur = space[2].cur = 3。

结果:备用链表变成 1→3→4→5→0,返回下标 2 给用户使用。

Free_SL —— 释放结点
void Free_SL(StaticList& space, int k)
{
space[k].cur = space[1].cur;  // 新释放的结点指向原备用链表头
space[1].cur = k;             // 让它成为新的备用链表头
}

举例:

当前空闲链表是 1→3→4→5→0

释放下标 2:

space[2].cur = space[1].cur = 3

space[1].cur = 2

新备用链表:1→2→3→4→5→0

Insert —— 插入节点(头插法)
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;
}
else                       // 链表非空
{
space[i].cur = space[0].cur;
}
space[0].cur = i;          // 更新头指针
}

举例:

假设 MAX_SIZE=6,此时空链表:space[0].cur = -1。

插入字符 'A':

分配到结点下标 2(假设)。

space[2].data = 'A',space[2].cur = -1。

更新 space[0].cur = 2。

链表:2→-1,对应内容:A。

再插入 'B':

分配下标 3。

space[3].data = 'B',space[3].cur = 2(指向原来的头)。

更新 space[0].cur = 3。

链表:3→2→-1,对应内容:B → A。

ShowSList —— 遍历打印
void ShowSList(StaticList& space)
{
int i = space[0].cur;
while (i != -1)
{
printf("%c-->", space[i].data);
i = space[i].cur;
}
printf("Nul.\n");
}

Delete —— 删除头节点
void Delete(StaticList& space)
{
int i = space[0].cur;          // 当前头结点
space[0].cur = space[i].cur;   // 头指针指向下一个
Free_SL(space, i);             // 释放旧的头结点
}

举例:

链表是 3→2→-1(内容:B→A)。

删除:

i = 3

更新 space[0].cur = space[3].cur = 2

释放结点 3 → 回到备用链表

新链表:2→-1(内容:A)。

posted on 2025-09-26 20:45  slgkaifa  阅读(32)  评论(0)    收藏  举报

导航