静态链表你学会了吗

最近在复习大学学习的静态链表数据结构,从代码分析结构,卡在了备用链表那里,通过画图分析才掌握了它的结构。

静态链表结构

首先我们先来看看静态链表的结构定义

typedef struct{
 
	ElemType data;
	int cur;
 
}Component,StaticLinkList[MAXSIZE];

如上面代码所示,静态链表需要预先分配容量为MAXSIZE的存储空间(接下来以MAXSIZE值为5进行演示),data定义了数据元素,cur定义了数据元素的游标(可以理解为指向下一节点的指针),用来指示下一数据元素的位置。这种数据结构,虽不能满足动态申请空间,但在线性表的插入和删除元素时,不需要移动元素,只需修改游标就能实现,故仍具有链式存储的主要优点。
静态链表初始化过程如下:

Status InitList(StaticLinkList L)
{
	int i;
 
	for(i = 0;i < MAXSIZE-2; i++)
	{
		L[i].cur = i+1;          //除备用链表最后元素,所有结点游标赋值为下一结点的下标
	}
	L[MAXSIZE-2].cur = 0; 		//备用链表的表尾 
	L[MAXSIZE-1].cur = 0;       //数据链表表头 
 
	return OK;
}

初始化为空的静态链表如下图一所示
在这里插入图片描述
图一 空的静态链表

在备用链表中插入数据

接下来才是重点!!!实际上静态链表分为两个链表:备用链表和数据链表(两表的表头位置如上图一所示)。备用链表将未使用空间串联起来,数据链表才是真正存放数据的地方,那么具体是怎样存储数据的呢?接下来我们在数据链表中插入数字1,看以下向数据链表中插入数据的代码:

Status InsertList(StaticLinkList L,int i,ElemType e)
{
	if(i<1||i>ListLength(L)+1)
		return ERROR;
 
	int j = Malloc_L(L);		//备用链表返回空闲数据元素下标以供插入元素 
	int k = MAXSIZE-1;			//数据链表表头的数据元素下标 
 
	if(j)						//判断备用链表非空
	{
		L[j].data = e;
 
		for(int s=1;s<=i-1;s++)
			k = L[k].cur;      	//从数据链表头结点遍历到第i-1个元素 
 
		L[j].cur = L[k].cur;	//将数据插入数据链表的第i-1个元素后 
		L[k].cur = j;			//将第i-1个元素的游标指向刚插入元素的位置
 
		return OK;
 
	}
    printf("备用链表为空!\n");
	return ERROR; //备用链表为空
 
}

Malloc_L函数用来返回备用链表表头所指向的第一个空闲空间(此空间将会转换成数据链表空间用来插入数据),此外Malloc_L函数还会修改备用链表表头的游标指向下一空闲空间。函数如下:

int Malloc_L(StaticLinkList L)
{
	int i = L[0].cur;
 
	if(L[0].cur)   				//备用链表非空
	{
		L[0].cur = L[i].cur; 	//更新备用链表首结点游标,让其指向下一空白节点
	}
 
	return i;
}

调用如下插入函数,其效果如下图二。

InsertList(L,1,1);

在这里插入图片描述
图二 向备用链表添加一个元素

图二中用红色字体标注的显然是数据链表了,剩下的黑体字标注的是备用链表,每当要插入一个数据时,备用链表中便有一块空间转化成数据链表的空间,其转换细节分为以下四个步骤:

  1. 记录备用链表头L[0]游标,更改L[0]游标为2,使其指向L[2],此时备用链表操作完成
  2. 给L[1]的数据元素赋值,L[1]将加入数据链表中
  3. 遍历数据链表L[4]到要插入位置(第i位置)的前一个数据元素(第i-1位置),将位于i-1位置的元素游标赋值给位于i位置的元素游标
  4. 将插入元素的位置i赋值给位于i-1位置的元素游标,数据链表的插入操作完成
    通过以上步骤的分析相信大家都已经熟悉了静态链表的插入操作,那么接下来再执行以下函数,你们能画出静态链表的数据结构图吗?
InsertList(L,1,2);

参考图如下,是不是画对了呢?

在这里插入图片描述
图三 向备用链表添加一个元素

关于静态链表的基本操作完整代码如下,欢迎大家一起交流学习

#include <stdio.h>
#define MAXSIZE   5
#define ERROR     0
#define OK        1
 
typedef bool Status;
typedef int  ElemType;
 
 
typedef struct{
 
	ElemType data;
	int cur;
 
}Component,StaticLinkList[MAXSIZE];
 
Status visit(ElemType c);									//刷出函数 
 
Status InitList(StaticLinkList L);							//初始化静态链表 
 	
int	Malloc_L(StaticLinkList L); 							//返回备用链表表头所指向的第一个空闲空间供插入元素,更新表头游标指向下一空闲空间
 
Status InsertList(StaticLinkList L,int i,ElemType e);
 
Status DeleteList(StaticLinkList L,int i);
 
void Free_L(StaticLinkList L,int j);
 
int ListLength(StaticLinkList L);
 
void OutList(StaticLinkList L);
 
int main()
{
	StaticLinkList L;
 
	InitList(L);
 
	printf("初始化后长度为:%d\n",ListLength(L));
 
	for(int i=1;i<=2;i++)
	{
		InsertList(L,1,i);
	}
	OutList(L);
	printf("插入两个元素后链表的长度为:%d\n",ListLength(L));
    
	DeleteList(L,2);
	
    OutList(L);
 
    printf("删除一个元素后链表的长度为:%d\n",ListLength(L));
 
	return 0;
}
 
 
Status InitList(StaticLinkList L)
{
	int i;
 
	for(i = 0;i < MAXSIZE-2; i++)
	{
		L[i].cur = i+1;          //除最后元素,所有结点游标赋值为下一结点的下标
	}
	L[MAXSIZE-2].cur = 0; 		//用链表的表尾 
	L[MAXSIZE-1].cur = 0;       //数据链表表头 
 
	return OK;
}
 
 
//返回备用链表表头所指向的第一个空闲空间供插入元素,更新表头游标指向下一空闲空间
int Malloc_L(StaticLinkList L)
{
	int i = L[0].cur;
 
	if(L[0].cur)   				//备用链表非空
	{
		L[0].cur = L[i].cur; 	//更新备用链表首结点游标 
	}
 
	return i;
}
 
 
Status InsertList(StaticLinkList L,int i,ElemType e)
{
	if(i<1||i>ListLength(L)+1)
		return ERROR;
 
	int j = Malloc_L(L);		//备用链表返回空闲数据元素下标以供插入元素 
	int k = MAXSIZE-1;			//数据链表表头的数据元素下标 
 
	if(j)						//备用链表非空
	{
		L[j].data = e;
 
		for(int s=1;s<=i-1;s++)
			k = L[k].cur;      	//从数据链表头结点遍历到第i-1个元素 
 
		L[j].cur = L[k].cur;	//将数据插入数据链表的第i-1个元素后 
		L[k].cur = j;
 
		return OK;
 
	}
    printf("备用链表为空!\n");
	return ERROR; //备用链表为空
 
}
 
Status DeleteList(StaticLinkList L,int i)
{
 
	if(i<1||i>ListLength(L)+1)
		return ERROR;
 
	int k = MAXSIZE-1;
	int j;
 
	for(int s=1;s<=i-1;s++)
		k = L[k].cur;
 
	j = L[k].cur;
	L[k].cur = L[j].cur;
	Free_L(L,j);
 
	return OK;
 
}
 
void Free_L(StaticLinkList L,int j)
{
	L[j].cur = L[0].cur;
	L[0].cur = j;
}
 
int ListLength(StaticLinkList L)
{
	int j=0;
	int i = L[MAXSIZE-1].cur;
	while(i)
	{
		i = L[i].cur;
		j++;
	}
 
	return j;
}
 
void OutList(StaticLinkList L)
{
	int j = 0;
	int i = L[MAXSIZE-1].cur;		//从数据链表开始遍历
	while(i)
	{
		visit(L[i].data);
		i=L[i].cur;
		j++;
	}
 
	printf("\n");
}
 
Status visit(ElemType c)
{
	printf("%d ",c);
	return OK;
}
  • 15
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
静态链表是一种使用数组实现的链表结构,它通过数组中的元素来模拟链表中的节点,并使用一个特殊的指针(游标)来表示节点之间的逻辑关系。静态链表的优点是实现简单,不需要频繁地申请和释放内存空间,但缺点是插入和删除操作比较麻烦,需要手动维护游标指针。 以下是一个简单的Python静态链表的实现示例[^1]: ```python class StaticLinkedList: def __init__(self, size): self.data = [None] * size # 存储数据的数组 self.next = [i + 1 for i in range(size)] # 游标数组,用于维护节点之间的逻辑关系 self.next[-1] = -1 # 最后一个元素的游标为-1,表示链表的末尾 self.head = -1 # 头指针,指向链表的第一个节点 def is_empty(self): return self.head == -1 def is_full(self): return self.next == -1 def insert(self, value): if self.is_full(): print("StaticLinkedList is full") return new_node = self.next # 获取一个空闲节点 self.next = self.next[new_node] # 更新空闲节点的游标 self.data[new_node] = value # 在空闲节点中存储数据 if self.is_empty(): self.head = new_node self.next[new_node] = -1 else: current = self.head while self.next[current] != -1: current = self.next[current] self.next[current] = new_node self.next[new_node] = -1 def delete(self, value): if self.is_empty(): print("StaticLinkedList is empty") return prev = -1 current = self.head while current != -1: if self.data[current] == value: break prev = current current = self.next[current] if current == -1: print("Value not found") return if prev == -1: self.head = self.next[current] else: self.next[prev] = self.next[current] self.next[current] = self.next # 将删除的节点加入空闲节点链表 self.next = current def display(self): if self.is_empty(): print("StaticLinkedList is empty") return current = self.head while current != -1: print(self.data[current], end=" ") current = self.next[current] print() # 创建一个容量为5的静态链表 static_list = StaticLinkedList(5) # 插入数据 static_list.insert(1) static_list.insert(2) static_list.insert(3) # 删除数据 static_list.delete(2) # 显示链表中的数据 static_list.display() ``` 输出结果为: ``` 1 3 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值