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

1.什么是静态链表

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

data ------ 存放数据

cur ------ 存放"下一个节点"的数组下标(就像 next 指针)

额外规则:

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

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

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

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

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

main.cpp

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

cpp 复制代码
#ifndef __STATICLIST_H__
#define __STATICLIST_H__

#include<stdio.h>

#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 ------ 初始化
cpp 复制代码
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,初始化后数组状态如下:

下标 data cur 说明
0 ? -1 表示链表为空
1 2 空闲链表第1个结点,指向2
2 3 空闲链表结点,指向3
3 4 指向4
4 5 指向5
5 0 空闲链表结束

此时:

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

真实链表 = 空

Malloc_SL ------ 分配结点
cpp 复制代码
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 ------ 释放结点
cpp 复制代码
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 ------ 插入节点(头插法)
cpp 复制代码
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 ------ 遍历打印
cpp 复制代码
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 ------ 删除头节点
cpp 复制代码
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)。

相关推荐
小卡皮巴拉3 小时前
【笔试强训】Day1
开发语言·数据结构·c++·算法
学不动CV了3 小时前
ARM单片机中断及中断优先级管理详解
c语言·arm开发·stm32·单片机·嵌入式硬件·51单片机
自信的小螺丝钉4 小时前
Leetcode 4. 两两交换链表中的节点 递归 / 迭代
leetcode·链表
༾冬瓜大侠༿4 小时前
数据结构:排序
数据结构·算法·排序算法
番茄大杀手4 小时前
C/C++柔性数组
c语言·柔性数组
冉佳驹5 小时前
C语言 ——— 操作符
c语言·操作符·隐式类型转换·原、反、补码·左移右移操作符·结构成员访问操作符·按位操作符
l1t5 小时前
测试duckdb的C插件模板的编译加工和加载
c语言·开发语言·数据库·插件·duckdb
.YM.Z7 小时前
数据结构——链表
数据结构·链表
自信的小螺丝钉7 小时前
Leetcode 148. 排序链表 归并排序
算法·leetcode·链表·归并