静态链表的基本操作(C语言版):链表的定义、初始化、创建、插入及删除

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41221623/article/details/79948983

这是我根据自身所学知识及参考一些代码实例写出来的静态链表的基本操作,如有哪些地方写的不够好,请大家多多指教。



静态链表初始化图例
0 2 3 4 5 6 7 8 …… 0
0 0 0 0 0 0 0 0 …… 0
0 1 2 3 4 5 6 7 …… 999

上表第一行表示游标,第二行表示数据,第三行表示数组下标
第二行的数据初始化时以0表示空


静态链表创建图例
6 2 3 4 5 0 7 8 …… 1
0 1 2 3 4 5 0 0 …… 0
0 1 2 3 4 5 6 7 …… 999


链表插入:
例如,在第6个位置插入22

静态链表插入图例
7 2 3 4 5 6 0 8 …… 1
0 1 2 3 4 5 22 0 …… 0
0 1 2 3 4 5 6 7 …… 999

链表删除:
例如删除第二个元素

静态链表删除图例
2 3 7 4 5 6 0 8
1
0 1 2 3 4 5 22 0 …… 0
0 1 2 3 4 5 6 7 …… 999

以上就是链表的初始化,创建,插入及删除原理,代码如下:

头文件 - Sq_List.h :

/*
 * 名称:《Sq_List.h》
 * 作用:定义关于静态链表的各种函数及常量
**/

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

/* 函数结果状态代码 */
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 1000		//链表的最大长度

typedef int Status;		//函数名,值为函数结果状态代码
typedef int ElemType;		//数据类型

/* 定义静态链表 */
typedef struct
{
	ElemType data;	//数据
	int cur;			//游标(Cursor)
}Component, StaticLinkList[MAXSIZE];

/* 静态链表初始化 */
Status InitList(StaticLinkList space);

/* 分配结点 */
int Malloc_SLL(StaticLinkList space);

/* 回收结点 */
void Free_SLL(StaticLinkList space, int k);

/* 计算静态链表长度 */
int ListLength(StaticLinkList L);

/* 静态链表插入 */
Status ListInsert(StaticLinkList L, int i, ElemType e);

/* 静态链表删除 */
Status ListDelete(StaticLinkList L, int i);

/* 打印链表 */
void Plist(StaticLinkList L);

/* 输入数据创建链表 */
void CreatList(StaticLinkList L);

实现头文件的C文件 - Sq_List.c :

/*
 * 名称:《Sq_List.c》
 * 作用:实现《Sq_List.h》中定义的函数
**/

#include "Sq_List.h"

/* 静态链表初始化 */
Status InitList(StaticLinkList space)
{
	//头结点记录的是备用链表的第一个结点的下标地址
	//尾结点记录第一个有数据的结点的下标
	//初始化时还未写入数据
	int i;
	for (i = 0; i < MAXSIZE - 1; i++)
	{
		space[i].data = 0;
		space[i].cur = i + 1;
	}
	space[0].cur = 0;
	space[MAXSIZE - 1].cur = 0;
	printf("初始化链表:\n");
	printf("\n***********************************\n\n");
	for (i = 0; i <= MAXSIZE - 1; i++)
	{
		printf("数据: %d  ——  游标: %d\n", space[i].data, space[i].cur);
	}
	printf("\n***********************************\n\n");
	return OK;
}

/* 分配结点 */
int Malloc_SLL(StaticLinkList space)
{
	int i = space[0].cur;
	if (space[0].cur)
	{
		space[0].cur = space[i].cur;
		//将备用链表的第一个结点抽出作待插入数据
		//space[0].cur重新指向新的备用链表的第一个结点的下标
	}
	return i;	//得到抽出的结点的下标,即原备用链表的第一个结点的下标
}

/* 回收结点 */
void Free_SLL(StaticLinkList space, int k)
{
	space[k].cur = space[0].cur;	//将被删除元素(即空闲结点)的游标指向备用链表的第一个结点的下标
	space[0].cur = k;				//将数组中的第一个元素的游标指向第一个没有数据的元素的下标,即间接的指向备用链表的第一个结点的下标
}

/* 计算静态链表长度 */
int ListLength(StaticLinkList L)
{
	int j = 0;
	int i = L[MAXSIZE - 1].cur;

	while (i)
	{
		i = L[i].cur;	//遍历静态链表中的元素,直到遍历到最后一个元素游标i为0
		j++;				//长度累加1
	}

	return j;			//返回长度
}

/* 静态链表插入 */
Status ListInsert(StaticLinkList L, int i, ElemType e)
{
	int j, k, l;

	k = MAXSIZE - 1;
	if (i < 1 || i > ListLength(L) + 1)	//i不在范围,返回错误
	{
		return ERROR;
	}

	j = Malloc_SLL(L);		//得到空闲分量的下标
	if (j)
	{
		L[j].data = e;		//将插入的新元素赋值给新分配的节点的数据域
		for (l = 1; l <= i - 1; l++)
		{
			k = L[k].cur;	//得到第i-1个元素的下标
		}
		L[j].cur = L[k].cur;	//将新元素的游标指向它的下一元素的下标
		L[k].cur = j;		//将第i-1个元素的游标指向插入的新元素的下标

		return OK;
	}

	return ERROR;
}

/* 静态链表删除 */
Status ListDelete(StaticLinkList L, int i)
{
	int j, k;
	if (i < 1 || i > ListLength(L))
	{
		return ERROR;
	}

	k = MAXSIZE - 1;

	for (j = 1; j <= i - 1; j++)
	{
		k = L[k].cur;		//得到第i-1个元素的下标
	}

	j = L[k].cur;		//获得要删除的元素的下标
	L[k].cur = L[j].cur; //将被删除的元素的前一个元素的游标指向它的后一个元素的下标

	Free_SLL(L, j);
	return OK;
}

/* 打印链表 */
void Plist(StaticLinkList L)
{
	int i = 0;
	for (i = L[MAXSIZE - 1].cur; L[i].cur != 0; i = L[i].cur)	//尾结点存放第一个有数据的结点的下标,从第一个开始遍历打印
	{
		printf("数据: %d  ——  游标: %d\n", L[i].data, L[i].cur);
	}
	printf("数据: %d  ——  游标: %d\n", L[i].data, L[i].cur);
}

/* 输入数据创建链表 */
void CreatList(StaticLinkList L)
{
	int i;		//从数组的第二个元素开始存储数据
	int x;		//x为优化变量,用来记录用户需要存储的数据的数量
	printf("\n请输入存储的数据的数量:");
	scanf("%d", &x);
	while (x > MAXSIZE - 2 || x < 1)		//判断是否超出链表最大限度以及非法输入
	{
		printf("超出链表最大限度或者非法输入(1 - %d),若想退出此操作请输入【 0 】:", MAXSIZE - 2);
		scanf("%d", &x);
		if (x == 0)
		{
			exit(0);
		}
	}
	printf("\n请依次输入存储的数据:");
	for (i = 1; i <= x; i++)
	{
		scanf("%d", &L[i].data);
	}
	L[x].cur = 0;			//尾元素游标指向0
	L[0].cur = x + 1;		//备用链表地址调整  
	L[MAXSIZE - 1].cur = 1;
}


主函数:

/*
 * 项目名称:《静态链表的基本操作》
 * 主要功能:实现静态链表的初始化、构建、插入、删除等操作。
 * 日期:2018-4-14
 * 作者:踏歌行彡轻盈
**/

#include <stdio.h>
#include <stdlib.h>
#include "Sq_List.h"

int main()
{
	int i, e;	//插入位置,插入元素
	int Di;		//删除位置
	StaticLinkList L;
	InitList(L);
	printf("\n初始化链表后,链表长度为%d\n\n", ListLength(L));
	CreatList(L);
	printf("\n创建链表后,链表长度为%d\n\n", ListLength(L));
	Plist(L);
	printf("\n");
	printf("请输入要插入的元素及插入的位置:");
	scanf("%d%d", &e, &i);
	ListInsert(L, i, e);
	printf("\n");
	Plist(L);
	printf("\n");
	printf("插入链表元素后,链表长度为%d\n", ListLength(L));
	printf("\n请输入要删除元素的位置:");
	scanf("%d", &Di);
	ListDelete(L, Di);
	printf("\n");
	Plist(L);
	printf("\n");
	printf("\n删除链表元素后,链表长度为%d\n\n", ListLength(L));
	return 0;
}

亲测运行结果如以下几图:







猜你喜欢

转载自blog.csdn.net/qq_41221623/article/details/79948983