【数据结构】——顺序表基本操作的实现详解

本文详细介绍了线性表中的顺序表数据结构,包括静态和动态顺序表的区别,并重点讲解了动态顺序表的实现,涵盖了初始化、增容、插入、删除、查找等基本操作。通过具体的C语言代码示例,展示了如何创建和操作顺序表,帮助读者深入理解顺序表的工作原理及其在实际中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

线性表是最基本、最简单、也是最常用的一种数据结构。
线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。
线性表是一种在实际中广泛使用的数据结构,常见的线性表: 顺序表、链表、栈、队列、字符串。…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
今天给大家介绍一下线性表中最简单一种: 顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表 顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中

顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
在这里插入图片描述
顺序表一般可以分为:
1.静态顺序表:
使用定长数组存储元素
在这里插入图片描述
2.动态顺序表:
使用动态开辟的数组存储
在这里插入图片描述

两种顺序表的比较:
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表的各个接口的基本操作。

接口实现

// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* psl, size_t capacity);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);

以上是我们要实现的接口功能。
接下来,我们一个一个的来具体分析、具体实现:
顺序表的动态存储:

//动态的顺序表结构
typedef int SQDataType;
typedef struct SeqList
{
	SQDataType* a;     //指向动态开辟的数组
	int size;          //有效数据的个数
	int capacity;      //容量空间的大小
}SLT;

顺序表初始化接口:

//初始化
void SeqListInit(SLT* psl)
{
	assert(psl);
	psl->a = NULL;
	psl->size = psl->capacity = 0;
}

顺序表销毁接口:

//销毁
void SeqListDestory(SLT* psl)
{
	assert(psl);
	if (psl->a)
	{
		free(psl->a);
		psl->a = NULL;
	}
	psl->size = psl->capacity = 0;
}

顺序表打印接口:

void SeqListPrint(SLT* psl)
{
	assert(psl);
	for (int i = 0; i < psl->size; ++i)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

顺序表检查增容:

//检查增容
void SeqListCheckCapcity(SLT* psl)
{
	assert(psl);
	//是否满了,满了就要增容
	if (psl->size == psl->capacity)
	{
		size_t newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
		psl->a = realloc(psl->a, newcapacity * sizeof(SQDataType));
		psl->capacity = newcapacity;
	}
}

顺序表尾插:

//尾插
void SeqListPushBack(SLT* psl, SQDataType x)
{
	assert(psl);
	//是否满了,满了就要增容
	SeqListCheckCapcity(psl);
	psl->a[psl->size] = x;
	psl->size++;
}

顺序表头插:

//头插
void SeqListPushFront(SLT* psl, SQDataType x)
{
	//SeqListInsert(psl, 0, x)
	assert(psl);
	SeqListCheckCapcity(psl);
	//挪动数据
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}
	psl->a[0] = x;
	psl->size++;
}

顺序表尾删:

//尾删
void SeqListPopBack(SLT* psl)
{
	assert(psl);
	//assert(psl->size > 0);

	//psl->a[psl->size - 1] = 0;
	if (psl->size > 0)
	{
		psl->size--;
	}
}

顺序表头删:

//头删
void SeqListPopFront(SLT* psl)
{
	assert(psl);
	//assert(psl->size > 0);
	int begin = 1;
	while (begin < psl->size)
	{
		psl->a[begin - 1] = psl->a[begin];
		begin++;
	}
	if (psl->size > 0)
	{
		psl->size--;
	}
}

顺序表查找接口:

//查找
int SeqListFind(SLT* psl, SQDataType x)
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

顺序表插入数据接口(2种):

//插入数据
//void SeqListInsert(SLT* psl, int pos, SQDataType x)
//{
//	assert(psl);
//	assert(pos < psl->size && pos>=0);
//	SeqListCheckCapcity(psl);
//	int end = psl->size - 1;
//	while (end >= pos)
//	{
//		psl->a[end + 1] = psl->a[end];
//		end--;
//	}
//	psl->a[pos] = x;
//	psl->size++;
//}
//插入数据
void SeqListInsert(SLT* psl, size_t pos, SQDataType x)
{
	assert(psl);
	assert(pos < psl->size);
	SeqListCheckCapcity(psl);
	size_t end = psl->size ;
	while (end > pos)
	{
		psl->a[end] = psl->a[end-1];
		end--;
	}
	psl->a[pos] = x;
	psl->size++;
}

顺序表删除数据接口:

//删除数据
void SeqListErase(SLT* psl, size_t  pos)
{
	assert(psl);
	assert(pos < psl->size);
	size_t begin = pos + 1;
	while (begin < psl->size)
	{
		psl->a[begin - 1] = psl->a[begin];
		begin++;
	}
	psl->size--;
}

顺序表求数组中数据个数:

size_t SeqListSize(SLT* psl)
{
	assert(psl);
	return psl->size;
}

顺序表修改pos位置的数据接口:

void SeqListAt(SLT* psl, size_t pos, SQDataType x)
{
	assert(psl);
	assert(pos < psl->size);
	psl->a[pos] = x;
}

以上就是顺序表的基本接口功能的实现,相信大家在看完之后,一定对顺序表方面的知识有所掌握和了解。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值