线性表之静态链表


静态链表存储结构

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

用数组描述链表叫做静态链表
结构由存放数据元素的数据域data和存放后继节点地址的cur作为游标组成


一、静态链表的初始化

目的:初始化静态链表的状态
实现:
①对静态链表第一个和最后一个元素进行特殊处理,他们不存数据
②第一个元素保存当前链表最后一个元素的下一个下标(空闲空间的第一个位置)
③最后一个元素保存第一个有数值元素的下标,相当于单链表中的头结点

void initList(StaticLinkList &L)
{
	for (int i = 0; i < MAXSIZE; i++)
	{
		L[i].cur=i+1;
	}
	L[MAXSIZE-1].cur=0;
}
在这里仅仅是初始化静态链表的状态,链表此时为空

所以第一个元素保存的是1,空闲空间的第一个位置是1,即此时链表中没有元素
最后一个元素保存第一个有数值元素的下标,因此为0


二、静态链表的插入

功能:在静态链表第l个元素前插入e
实现:
①定义j获取当前链表中第一个空闲位置的坐标(Malloc_SLL)
②将想插入的e赋值给空闲位置的data,从末位L[MAXSIZE-1]cur开始遍历找到第l-1个元素
③将第l-1个元素的cur赋值给插入元素的cur
④再将插入元素的下标赋值给第l-1个元素

void ListInsert(StaticLinkList &L,int l,int e)
{
	int k=MAXSIZE-1;
	if (l<1||l>ListLength(L)+1)
	{
		cout<<"error!"<<endl;
		return ;
	}
	int j=Malloc_SLL(L);
	if (j)
	{
		L[j].data=e;
		for (int i = 1; i <= l-1; i++)
		{
			k=L[k].cur;
		}
		L[j].cur=L[k].cur;
		L[k].cur=j;
		cout<<"inserted successfully!"<<endl;
		return ;
	}
	cout<<"error!"<<endl;
}
这样就可以不动声色地插入元素到链表中,通过cur进行遍历时,第l-1个元素的cur为插入元素的位置(即之前空闲的第一个位置),接着插入元素的cur为第l-1个元素之前的cur(即指向第l个元素的位置),继续遍历回到第l个元素,遍历是连续的

相当于从第l-1个位置跳到插入元素的位置再回到第l个元素的位置

实现Malloc_SLL()函数

功能:在这里需要自己实现类似malloc()函数分配空间的功能
实现:返回空闲空间的第一个位置的下标
并把空闲空间第二个位置下标赋给第一个元素
如果链表为空返回0

int Malloc_SLL(StaticLinkList &L)
{
	int i=L[0].cur;
	if (i)
	{
		L[0].cur=L[i].cur;
	}
	return i;
}
因为第一个元素的cur为空闲位置的第一个坐标,在这里Malloc_SLL()实现分配一个元素空间的功能,所以空闲位置的第一个坐标已被分配,所以此时第一个元素的cur应指向空闲位置的第二个坐标

三、静态链表的读取

功能:读取静态链表中第i个元素的值
实现:
①利用k作为游标,向后移动k,直到k为第i个元素的位置
③输出元素的值

void GetElem(StaticLinkList &L,int i)
{
	int k=L[MAXSIZE-1].cur;
	if(i>ListLength(L)) 
	{
		cout<<"have not found this element!"<<endl;
		return ;
	}
	for (int j = 1; j <= i-1; j++)
	{
		k=L[k].cur;
	}
	cout<<L[k].data<<endl;
}

实现ListLength()函数

功能:返回静态链表的长度
实现:
①利用i作为游标,赋值i为第一个有数据元素的位置
②向后遍历,累加len,当i==0时说明到达链表最后一个数据元素的位置

int ListLength(StaticLinkList &L)
{
	int len=0;
	int i=L[MAXSIZE-1].cur;
	while (i)
	{
		i=L[i].cur;
		len++;
	}
	return len;
}

四、静态链表的删除

功能:删除单链表中第i个元素
实现:
①利用k作为游标,向后移动k,直到k为第i-1个元素的位置
②将第i-1个元素的cur赋值给j,此时j为第i个元素的位置
③将j的cur(即第i个元素的cur)赋值给第i-1(k)个元素
④“释放“L中第i个元素

void ListDelete(StaticLinkList &L,int i)
{
	if (i<1||i>ListLength(L))
	{
		cout<<"error!"<<endl;
		return ;
	}
	int k=MAXSIZE-1;
	for (int j = 1; j < i; j++)
	{
		k=L[k].cur;
	}
	int j=L[k].cur;
	L[k].cur=L[j].cur;
	Free_SSL(L,j);
	cout<<"deleted successfully"<<endl;
}
这里相当于跳过了第i个结点,使i-1的cur为第i个元素的cur,再“释放”第i个元素

实现Free_SSL()函数

功能:在这里需要自己实现类似free()函数释放空间的功能
实现:
①将当前空闲空间的第一个元素位置赋给释放元素的cur
②再将所释放元素的位置赋给第一个元素的cur作为空闲空间的第一个元素

void Free_SSL(StaticLinkList &L,int i)
{
	L[i].data=0;
	L[i].cur=L[0].cur;
	L[0].cur=i;
}
将删除后的元素“归还“空闲空间”

五、静态链表的整表删除

功能:清空整个静态链表
实现:
①将最后一个元素的cur(指向第一个有数据的元素)赋给i
②遍历链表,释放结点
③将最后一个元素cur赋为0

void ClearList(StaticLinkList &L)
{
	int i=L[MAXSIZE-1].cur;
	while (i)
	{
		int j=i;
		i=L[i].cur;
		Free_SSL(L,j);
	}
	L[MAXSIZE-1].cur=0;
	cout<<"cleared successfully!"<<endl;
}

六、显示静态链表中的数据

功能:显示所有数据
实现:将最后一个元素的cur(指向第一个有数据的元素)赋给i遍历输出即可

void show(StaticLinkList &L)
{
	int i=L[MAXSIZE-1].cur;
	while (i)
	{
		cout<<L[i].data<<"->";
		i=L[i].cur;
	}
	cout<<"0"<<endl;
}

总结

本篇介绍了对静态链表的创建、插入、删除等操作。静态链表其实是为了没有指针的高级语言设计的一种单链表,虽然不一定能用到,但我们应该理解这种思维方式。

测试代码及运行实例

int main()
{
	StaticLinkList a;
	initList(a);
	show(a);
	for (int i = 1; i <= 7; i++)
	{
		ListInsert(a,i,i);
	}
	show(a);
	ListInsert(a,5,500);
	show(a);
	ListDelete(a,5);
	show(a);
	GetElem(a,5);
	show(a);
	ClearList(a);
	show(a);
	return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新西兰做的饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值