静态链表(1)

什么叫静态链表?——用顺序表模拟链表,就叫做静态链表

第一列相当于数据域data,第二列相当于指针域next,

第一行(0)相当于头结点(头结点的数据域不放数据)

(a)图中0的next是1,1的next是2,……7的next是8,8的next是0,一遍下来又返回头结点

所以静态链表模拟的是——循环链表

这张图片中有一个姓氏是被删掉不存在也就是无效(之前说过数组中的数据域都是有数字的,只不过有些数字有效,有些数字无效,无效的数字在数组中就当做不存在)的,可以看出来是第7个ZHENG

所以数组中有一个有效数据长度length,length为几,这个数组的有效数据就是几

其余数据可能是0,也可能是其他数字,不过均无效

因为通过next的数字将每个格子串起来,发现串完一遍回到0后,7不在这串的里面(且指针域里面也没有7).

而在静态链表中,找空闲结点的时间复杂度为——O(n^2)。并不是O(n)

因为如果要看1是不是空闲结点,就要从头到尾串一遍,看看1在不在这个串里面(数组中的所有指针域里面有没有1出现过),同理2到n,每个都要遍历一遍,n个n遍为n方。

如果已知有一个空闲结点的情况下是遍历一次(所以有的说On),但若是有5000个结点,且不知道里面一共有几个空闲结点时,且第几个为空闲结点时,那就每个结点都需要遍历一遍看看在不在里面了。——时间复杂度取最坏的可能情况第5000个

其时间复杂度太大,但对于我们来说,我们使用链表最常用的操作是————头插尾插按值删。

前面指针类型的链表在头插尾插按值删的时候,每次插入我们都要malloc申请一个结点,每次删除我们要free释放p结点。(老是跟外部的空间也会有影响)

而静态链表是为了解决这个(频繁malloc申请free释放,造成内存的碎片化)麻烦的。

它一次给你总数固定的格子点数(不扩容的情况下),比如图中的给你10个点,然后你在里面插入删除

而在静态链表里面,要想插入,只要找到空闲结点O(n^2),将要插入的有效数据val赋值覆掉原来的无效数据O1,盖然后把它接入(先绑后,再接前)到有效数据链里面O1,就完成了。(时间复杂度为O(n^2))

要想删除,只要找到要删除的结点,然后把它从有效数据链里面踢出去,接入到无效空闲数据链里面,就完成了。

所以静态链表要改一下设计(为了缩小原来找空闲结点的时间复杂度),上图中a,b图就不对了

改造就是————把所有的空闲结点串起来,这样就找的快,

找空闲结点的时间复杂度就能降为O(1)

所以上图中就要划分为2张链表,一个链叫有效数据链,一个链叫空闲数据链,也就叫空闲链。

然后插入就是你去找你就从空闲链里拿出去,然后插入到有效链里。

然后规定,0号位置作为有效链的头结点,1号位置作为无效链的头结点,

那么该静态链表的结构设计要怎么做:看图写话

其内部成员就有,int data和int next

一个结点就是一个SNode即

MAXSIZE就是一个静态链表里面有多少对这样的

头文件中的函数声明

#pragma once

#define MAXSIZE 10
typedef struct SNode
{
	int data;//数据域
	int next;//后继指针,表示下一个结点的意思(实际上就是数组中的下标)
}SNode,SLinkList[MAXSIZE];

//SLinkList s;//s是一个长度为MAXSIZE的结构体数组,s指向该数组

//初始化
void InitList(SNode* ps);

//头插
bool Insert_head(SNode* ps, int val);

//尾插
bool Insert_tail(SNode* ps, int val);

//插入数据,在链表plsit的pos位置插入val数据元素,这个不写了,静态链表不考这么深

//判空
bool IsEmpty(SNode* ps);

//获取数据结点的个数
int Getlength(SNode* ps);

//在链表ps中 查找第一个key值,找到返回key值的结点下标,没有找到返回-1
int Search(SNode* ps, int key);

//删除链表ps中pos位置的值,删除跟插入一样成功或失败2种结果,这个也不写


//删除第一个val的值
bool DelVal(SNode* ps, int val);

//返回key的前驱地址,返回key的后继下标,这些也不写

//输出
void Show(SNode* ps);

//清空链表中的数据
void Clear(SNode* ps);

//销毁整个链表内存(交回)
void Destroy(SNode* ps);

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值