数据结构 -- 静态链表代码实现(总结)

Posted 庸人冲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 -- 静态链表代码实现(总结)相关的知识,希望对你有一定的参考价值。

静态链表是利用数组代替指针来描述单链表,数组的每一个元素都由两个数据域组成,datacurdata用来存放数据,cur用来存放下一个元素的在数组中的下标,cur也被称作游标。

此外整个链表也被逻辑划分为两个部分:已使用链表备用链表,我们对数组的首元素和尾元素进行特殊处理,不存数据。首元素cur中存放备用链表第一个元素的下标;而尾元素cur中存放已使用链表的第一个元素的下标,当尾元素cur为0时说明链表为空。

当链表有存储数据时,已使用链表中的最后一个元素的cur为0。

特点

  1. 静态链表利用游标来索引到下一个元素,每次删除和添加元素时只需要修改cur值,不需要移动元素。改进了顺序存储结构每次添加和删除都需要移动大量元素的缺点。
  2. 静态链表没有解决连续存储分配带来表长难以确定的问题。失去链式存储结构随机存储的特性。

代码实现

#define _CRT_SECURE_NO_WARNINGS 1 
#include <stdio.h>


#define OK 1       // 状态返回值
#define ERROR 0    // 状态返回值
#define FALSE 0    // 状态返回值
#define TRUE       // 状态返回值
#define MAXSIZE 1000   // 数组最大容量

typedef int ElemType;   // 数据元素类型
typedef int Status;     // 函数操作状态返回类型

// 定义静态链表结构
typedef struct StaticList {
	ElemType data;    // 数据域
	int cur;          // 游标
}component, StaticList[MAXSIZE];


// 初始化
Status InitList(StaticList SL)
{
	int j = 0;
	for (j = 0; j < MAXSIZE - 1; j++)
	{
		SL[j].cur = j + 1;               // 初始化,使每个元素的`cur`都存放下一个元素的下标
	}
	SL[MAXSIZE - 1].cur = 0;             // 最后一个元素的`cur`初始化为0
	return OK;
}

// 获取表长
int Listlength(const StaticList SL)
{

	int k = SL[MAXSIZE - 1].cur;  // 从第一个元素开始
	int count = 0;                // 计数器
	while (k)                     // k 不为0,则说明该元素存在,进入循环
	{
		count++;                  // 计数器+1
		k = SL[k].cur;            // 不断向后移动
	}
	return count;                // 返回count

}

// 打印元素
void print(ElemType e)
{
	printf("%d ", e);
}


// 遍历表
void ListTraverse(StaticList SL)
{
	int k = SL[MAXSIZE - 1].cur;    // 从第一个元素开始遍历
	while (k)                    // 直到k为 0时 结束
	{
		print(SL[k].data);      // 将数据传给print函数进行打印
		k = SL[k].cur;
	}
	printf("\\n");
}


// 备用链表中分配新空间
// 返回新空间的下标
int Malloc_SSL(StaticList SL)
{
	int s = SL[0].cur;     // 链表首元素的 cur 存放的是备用链表第一个元素的下标,将该下标赋值给 s
	if (s)                 // 如果 s 不为0 说明表未满
	{
		SL[0].cur = SL[s].cur;  // 既然 s 被分配,则让首元素的 cur 存放 s 后面元素的下标。 
	}
	return s;
}

// 释放被删除元素空间
// 该空间会被放入备用链表第一个位置
void Free_SSL(StaticList SL, int q)
{
	SL[q].cur = SL[0].cur;   // 首元素的cur 赋值给被释放空间的 cur
	SL[0].cur = q;           // 首元素的cur 存放被释放空间的下标, 此时下标为q的空间是备用链表第一个位置。
}


// 插入元素
// 将指定元素 e 插入到指定位置 i 
Status ListInsert(StaticList SL, int i, ElemType e)
{
	// 判断 i 的值是否合适
	if (i < 1 || i > Listlength(SL) + 1)
	{
		return ERROR;
	}
	// 申请新空间
	int s = 0;
	s  =  Malloc_SSL(SL);
	if (s)    // 如果 s 不为0,说明空间分配成功
	{
		SL[s].data = e;        // 将指定元素插入到 SL[s].data 中
		int k =  MAXSIZE - 1;
		int j = 0;
		for (j = 1; j < i; j++)  // 移动到插入位置 i 之前
		{
			k = SL[k].cur;
		}
		SL[s].cur = SL[k].cur;   // 新插入元素.cur 存放指定位置 i 元素的下标
		SL[k].cur = s;           // i 的前驱元素.cur 则存放 s 
		return OK;
	}
	return ERROR;
}

// 删除元素
// 删除指定位置上的元素,并用 e 返回该元素的值
Status ListDelete(StaticList SL, int i, ElemType *e)
{
	if (i  < 1 || i > Listlength(SL))
	{
		return ERROR;
	}
	// 找到第i个位置前的元素
	int k = MAXSIZE - 1;
	int j = 0;
	for (j = 1; j < i; j++)
	{
		k = SL[k].cur;
	}
	// 使得 i - 1元素 与 i + 1元素建立联系
	int q = SL[k].cur;        // 保存被删除元素的下标
	SL[k].cur = SL[q].cur;    // 使得被删除元素之前元素的 cur 保存为之后元素的下标
	// 删除 i 位置元素
	*e = SL[q].data;           // 返回被删除元素的值
	Free_SSL(SL, q);
	
}

// 获取元素
// 通过位置,获取到元素,并使用 e 返回该元素
Status GetElem(StaticList SL, int i, ElemType* e)
{
	if (i < 1 || i > Listlength(SL))
	{
		return ERROR;
	}
	// 找到第i个元素
	int k = SL[MAXSIZE - 1].cur;  // 从第一个元素开始遍历
	int j = 0;
	for (j = 1; j < i; j++)
	{
		k = SL[k].cur;            // 不断向后遍历,直到i之前结束
	}
	*e = SL[k].data;
	return OK;
	
}


int main()
{
	// 创建静态链表
	StaticList SL;

	// 创建接收状态返回值变量
	Status sta;

	// 创建接收元素返回值变量
	ElemType e;

	// 初始化静态链表
	sta = InitList(SL);
	printf("初始化是否成功?【%d】(1.成功 0.失败)\\n",sta);

	// 插入元素
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		ListInsert(SL, i, i);
	}
	
	// 遍历表
	printf("插入元素后:");
	ListTraverse(SL);
	printf("表长为:%d\\n", Listlength(SL));
	

	// 删除元素
	ListDelete(SL, 5,&e);
	printf("删除元素为:%d\\n", e);
	printf("删除元素后:");
	ListTraverse(SL);
	printf("表长为:%d\\n", Listlength(SL));

	// 获取元素
	GetElem(SL, 5, &e);
	printf("获取的元素为:%d\\n", e);

	return 0;
}

以上是关于数据结构 -- 静态链表代码实现(总结)的主要内容,如果未能解决你的问题,请参考以下文章

静态链表循环链表双向链表(C代码实现)

静态链表代码

数据结构--单链表简单代码实现(总结)

数据结构之线性表代码实现顺序存储,链式存储,静态链表(选自大话数据结构)

链式存储结构之静态链表

结对作业1