静态链表相关概念及其操作

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

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);
在这里插入图片描述
图二 向备用链表添加一个元素

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

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

在这里插入图片描述

//综合代码

#include"staticlist.h"
int main()
{

	int i = 0, n = 0;

	staticlist space;

	initstaticlist(space);

	printstaticlist(space);

	printf("\n");
		
	insertstaticlist(space, 1,1);	

	insertstaticlist(space, 2, 2);

	printstaticlist(space);

	printf("\n");

	insertstaticlist(space, 3, 6);

	printstaticlist(space);//按数组下标输出

	printf("\n");

	system("pause");

	return 0;

}
#include"staticlist.h"

int initstaticlist(staticlist l)
{
	int i = 0;

	for (i = 0; i < max-1; i++)
	{

		l[i].next=i+1;

	}

	//通常数组第一个下标和最后一个下标的数据域不用,这里先把它初始化为0
	l[max - max].data = 0;
	l[max - 1].data = 0;

	l[max - 1].next = 0;

	return 1;
}

int lengthstatic(staticlist l)
{
	int i = 0, j = 0;

	i = l[max - 1].next;//最后一个数组元素(l[9].next)的游标相当于头节点,它指向第一个有数据元素链表的数组下标

	while (i)
	{
		i = l[i].next;//当i为0时,即遍历到了有数据元素的数组的最后一个元素,相当于单链表表尾指针域的NULL

		j++;//记录元素个数

	}

	return j;

}

void printstaticlist(staticlist l)
{
	int i = 0;

	for (i = 0; i < max; i++)
	{
		printf("i:%d   next:%d   data:%d\n", i, l[i].next, l[i].data);

	}
}

void printcursor(staticlist l)
{

	int i = 0, k = 0;

	k = l[max - 1].next;

	while (k)
	{
		printf("%d\n", l[k].data);

		k = l[k].next;
		
	}

	return;

}

int malloc(staticlist l)
{
	int cursor = l[0].next;//返回备用链表当中没有数据元素的第一个数组元素的下标

		if (l[0].next)
		{
			l[0].next = l[cursor].next;

	    }
		return cursor;
}

void insertstaticlist(staticlist l,int i,int value)
{
	int k = max - 1;

	int j = 0, n = 0;

	if (i < 1)
	{
		return;
	}

	j = malloc(l);

	if (j)
	{
		l[j].data=value;

		for (n = 1; n <= i - 1; n++)
		{

			k = l[k].next;

		}

		l[j].next= l[k].next;

		l[k].next=j;

	}
    return ;
}

void free_ssl(staticlist l,int k)//将下标为k的空闲节点回收为备用链表
{

	l[k].next = l[0].next;

	l[0].next = k;

}

int delstaticlist(staticlist l, int i)
{
	int j = 0, k = 0;

	k = max - 1;

	if (i < 1)
	{
		return 0;
	}

	for (j = 1; j <= i - 1; j++)
	{

		k = l[k].next;

	}

	j = l[k].next;//这两句的意思是如果有元素被删除了,就更新最后一个数组元素的游标

	l[k].next = l[j].next;

	free_ssl(l, j);//如果有新的元素插进来,就优先考虑以前删除的空位置

	return 1;

}
#ifndef   _staticlist_h
#define   _staticlist_h

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#define max  10

typedef struct node
{
	int data;
	int next;
}staticlist[max];

extern int initstaticlist(staticlist l);
extern void printstaticlist(staticlist l);
extern void printcursor(staticlist l);
extern int lengthstatic(staticlist l);
extern int malloc(staticlist l);
extern void insertstaticlist(staticlist l, int i, int value);
extern void free_ssl(staticlist l, int k);
extern int delstaticlist(staticlist l, int i);
#endif

参考:https://blog.csdn.net/zk25257758/article/details/103530626

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值