数据结构之静态链表

静态链表

结构体的一个成员存放数据,另一个成员(“游标”)存放下一个数的位置(下标),这称为静态链表。输出链表不是按数组的下标顺序输出的,而是由一个指定的位置开始根据游标依次输出的。
将所有空闲结点链接形成一个备用链表,数组下标为 0 的单元为备用链表的头结点(这时,链表的头结点就不能再是数组下标
为 0 的单元了,需要另外定义)。静态数组实际有 2 个链表,一个链表上链接的是线性表的结点,另一个链表(备用链表)上链接的是所有没被使用的结点。静态数组的每一个元素都链接在这 2 个链表中的一个上。当线性表需要新结点时,把备用链表中的首元结点(由[0].cur 指示)从备用链表中删除,作为新结点,插入线性表。当删除线性表中的结点时,被删除的结点插入备用链表中,成为备用链表的首元结点。之所以从备用链表删除结点或向备用链表插入结点都在表头进行,是因为这样效率最高。

静态链表的定义

#include<stdio.h>
#include<malloc.h>

//一个数组只生成一个静态链表

#define	MAX_SIZE 100	//链表的最大长度
#define Destroy Clear	//Destroy()和Clear()的操作是一样的

//线性表的静态单链表存储结构
typedef struct
{
	int data;	//存放数据
	int cur;	//游标,相当于指针,记录下一结点位置
}component,List[MAX_SIZE];

在这里List是结构体数组类型。

List L;
//等价于
struct component L[MAX_SIZE];

比如

typedef int arr[5];

arr a;就定义了一个有5int型变量的数组a。

基本操作

#include<stdio.h>
#include<malloc.h>

//一个数组只生成一个静态链表

#define	MAX_SIZE 100	//链表的最大长度
#define Destroy Clear	//Destroy()和Clear()的操作是一样的

//线性表的静态单链表存储结构
typedef struct
{
	int data;
	int cur;
}component,List[MAX_SIZE];

//基本操作
void Init(List L);	//构造一个空的链表
void Clear(List L);	//将L置为空表
bool Empty(List	L);	//判断L是否为空表
int Length(List L);	//返回链表长度
bool Get(List L,int i,int e);	//用e返回L中第i个数据元素
int Locate(List L,int e);	//返回第一个值为e的元素的位序
bool Priorm(List L,int cur_e,int *pre_e);//用pre_e返回cur_e元素的前驱
bool Next(List L,int cur_e,int *next_e);//用next_e返回cur_e元素的后继
bool Insert(List L,int i,int e);//在第i个元素之前插入数据元素e
bool Delete(List L,int i,int *e);//删除第i个数据元素用e保存
int Malloc(List space);	//若备用链表非空,则返回分配的结点下标
void Free(List space,int k);//将下标为k的空闲结点回收到备用链表(成为备用链表的第一个结点)
void Traverse(List L);	//遍历

void Init(List L)
{
	//构造一个空的链表L,表头为L的最后一个单元L[MAX_SIZE-1],
	//其余单元链成一个备用链表,表头为L的第一个单元L[0],"0"表示空指针
	int i;
	L[MAX_SIZE-1].cur=0;	//L的最后一个单元为空链表的表头
	for(i=0;i<MAX_SIZE-2;i++)	//将其余单元链接成以L[0]为表头的备用链表
		L[i].cur=i+1;
	L[MAX_SIZE-2].cur=0;
}
void Clear(List L)
{
	int i,j,k;
	i=L[MAX_SIZE-1].cur;	//链表第一个结点的位置
	L[MAX_SIZE-1].cur=0;	//链表空
	k=L[0].cur;				//备用链表第一个结点的位置
	L[0].cur=i;				//把链表的结点连到备用链表的表头
	while(i!=0)
	{
		j=i;
		i=L[i].cur;			//指向下一个元素
	}
	L[j].cur=k;				//备用链表的第一个结点接到链表的尾部
}
bool Empty(List L)
{
	if(L[MAX_SIZE-1].cur==0)
		return true;
	else
		return false;
}
int Length(List L)
{
	int i=L[MAX_SIZE-1].cur;
	int count=0;	//临时存放链表元素个数
	while(i!=0)
	{
		count++;
		i=L[i].cur;
	}
	return count;
}
bool Get(List L,int i,int *e)
{
/*	int k=L[MAX_SIZE-1].cur;
	int j=1;	
	while(j<i&&k!=0)
	{
		j++;
		k=L[k].cur;
	}
	if(j>i||k==0)
		return false;
	*e=L[k].data;
	return true;
*/
	int j,k=MAX_SIZE-1;//k指向表头序号
	if(i<1||i>Length(L))
		return false;
	for(j=1;j<i;j++)
		k=L[k].cur;
	*e=L[k].data;	
}
int Locate(List L,int e)
{
	int i=L[MAX_SIZE-1].cur; // i指示表中第一个结点
	while(i&&L[i].data!=e) // 在表中顺链查找(e不能是字符串)
		i=L[i].cur;
	return i;
}
bool Priorm(List L,int cur_e,int *pre_e)
{
	int j,i=L[MAX_SIZE-1].cur;	//i指示链表第一个位置
	do{
		j=i;
		i=L[i].cur;
	}while(i!=0&&cur_e!=L[i].data);
	if(i!=0)
	{
		*pre_e=L[j].data;
		return true;
	}
	return false;
}
bool Next(List L,int cur_e,int *next_e)
{
	int j,i=Locate(L,cur_e);
	if(i)
	{
		j=L[i].cur;	//cur_e后继的位置
		if(j)		//cur_e有后继
		{
			*next_e=L[j].data;
			return true;
		}
	}
	return false;
}
bool Insert(List L,int i,int e)
{
	int l,j,k=MAX_SIZE-1;	//k指向表头
	if(i<1||i>Length(L)+1)
		return false;
	j=Malloc(L);	//申请新单元
	if(j)			//申请成功
	{
		L[j].data=e;	//赋值给新单元
		for(l=1;l<i;l++) // 移动i-1个元素
			k=L[k].cur;
		L[j].cur=L[k].cur;
		L[k].cur=j;
		return true;
	}
	return false;
}
bool Delete(List L,int i,int *e)
{
	int j,k=MAX_SIZE-1; // k指向表头
	if(i<1||i>Length(L))
		return false;
	for(j=1;j<i;j++) // 移动i-1个元素
		k=L[k].cur;
	j=L[k].cur;
	L[k].cur=L[j].cur;
	*e=L[j].data;
	Free(L,j);
	return true;
}
int Malloc(List space)
{ 
	// 若备用链表非空,则返回分配的结点下标(备用链表的第一个结点);否则返回0
	int i=space[0].cur;
	if(i) // 备用链表非空
		space[0].cur=space[i].cur; // 备用链表的头结点指向原备用链表的第二个结点
	return i; // 返回新开辟结点的坐标
}
void Free(List space,int k)
{ 
	// 将下标为k的空闲结点回收到备用链表(成为备用链表的第一个结点)
	space[k].cur=space[0].cur; // 回收结点的"游标"指向备用链表的第一个结点
	space[0].cur=k; // 备用链表的头结点指向新回收的结点
}
void Traverse(List L)
{
	int i=L[MAX_SIZE-1].cur; // 指向第一个元素
	while(i) // 没到静态链表尾
	{
		printf("%d ",L[i].data);
		i=L[i].cur; // 指向下一个元素
	}
	printf("\n");
}
int main()
{
	List L;
	Init(L);
	Insert(L,1,1);
	Insert(L,2,2);
	Insert(L,3,3);
	Insert(L,4,4);
	Insert(L,5,5);
	printf("插入的元素为:");
	Traverse(L);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42447402/article/details/85866280