数据结构---顺序表

文章目录

线性表

线性表的定义

  • 线性表是n个具有相同属性的数据元素的有限序列。
  • 线性表在逻辑上是线性结构,也就是说连续的一条直线。但是在物理结构上不一定是连续的
  • 线性表在物理结构(存储结构)上一般采用顺序和链式的形式存储

线性表分类

顺序表

顺序表是用一段物理地址连续的存储单元存储元素的线性结构,一般采用数组进行存储。在数组上完成数据元素的增删查改

顺序表一般分为:

  • 静态顺序表:使用定长的数组存储
  • 动态顺序表:使用动态开辟的数组存储

静态顺序表只适合确定需要存储多少数据的场景,如果存储数据量不确定的话,空间开太大浪费,开太小不够用。一般都会去使用动态顺序表,根据情况分配多大的空间。下面将介绍动态顺序表

顺次表的存储结构

图示

cpp 复制代码
typedef int ElemType;
typedef struct SeqList
{
	ElemType* a;
	int size;
	int capacity;
}SeqList;

定义一个动态顺序表需要三个属性

1.存储空间的地址,需要一段空间来维护顺序表,需要知道顺序表的起始地址

2.顺序表的元素个数,记录顺序表的元素个数,

3.顺序表的空间容量,用来分配空间

实现顺序表的主要接口函数

cpp 复制代码
//顺序表初始化
void SeqListInit(SeqList* ps);
//顺序表尾插
void SeqListPushBack(SeqList* ps, ElemType x);
//检查容量
void CheckCapicity(SeqList* ps);
//顺序表尾删
void SeqListPopBack(SeqList* ps);
//顺序表头插
void SeqListPushFront(SeqList* ps, ElemType x);
//顺序表头删
void SeqListPopFront(SeqList* ps);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, ElemType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
//打印顺序表
void SeqListprintf(SeqList* ps);
//销毁顺序表
void DestroyedSeqList(SeqList* ps);

初始化顺序表

这里先为顺序表申请了2个元素类型的空间大小。

cpp 复制代码
void SeqListInit(SeqList* ps)
{
	ps->a = (ElemType*)malloc(sizeof(ElemType)*2);
	ps->size = 0;
	ps->capacity = 2;
}

顺序表尾插

在尾部插入的时候要考虑两种情况,分别是

  • 顺序表未满尾插:直接将元素放入尾部即可
  • 顺序表已满的情况下,则需要申请更大的空间来存放数据


代码实现:

cpp 复制代码
void SeqListPushBack(SeqList* ps, ElemType x)
{
	assert(ps);
	//检查容量
	CheckCapicity(ps);
	//尾插
	ps->a[ps->size] = x;
	ps->size++;
}

这里将检查容量封装成一个函数,方便后面插入检查继续复用

cpp 复制代码
void CheckCapicity(SeqList* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity * 2;
		ElemType* tmp = (ElemType*)realloc(ps->a,sizeof(ElemType)*newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

顺序表尾删

在尾删时,也应该考虑两种情况,分别是

-顺序表已空时,无需删除

-顺序表未空,直接删除尾部元素即可

代码实现 :

这里提供两种写法,一种是暴力检查,程序直接崩溃,一种是防止越界程序可以正常运行

  • 暴力检查版
cpp 复制代码
void SeqListPopBack(SeqList* ps)
{
	//判空
	assert(ps->size > 0);//如果尾删空顺序表,程序直接崩溃
	//删除
	--(ps->size);
}
  • 防止越界版
cpp 复制代码
void SeqListPopBack(SeqList* ps)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//删除
	--(ps->size);
}

顺序表头插

和尾插一样,要考虑是否有空间,但是与尾插不同的地方在于,需要挪动数据进行插入
图解


代码实现

cpp 复制代码
void SeqListPushFront(SeqList* ps, ElemType x)
{
	//检查容量
	CheckCapicity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//插入
	ps->a[0] = x;
	++ps->size;
}

顺序表头删

头删和尾删一样,先判空。与尾删不一样的地方在于删完后需要挪动数据
图解


代码实现

cpp 复制代码
void SeqListPopFront(SeqList* ps)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//挪动数据覆盖删除
	int start = 0;
	while (start <= ps->size) 
	{
		ps->a[start] = ps->a[start + 1];
		start++;
	}
	--ps->size;
}

在指定位置插入数据

和头插的思想基本一样
图解


代码实现

cpp 复制代码
void SeqListInsert(SeqList* ps, int pos, ElemType x)
{
	//检查容量
	CheckCapicity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//插入
	ps->a[pos] = x;
	++ps->size;
}

在指定的位置删除数据

思想与头删基本一样
图解


代码实现

cpp 复制代码
void SeqListErase(SeqList* ps, int pos)
{
	//判空
	if (ps->size == 0)
	{
		return;
	}
	//挪动数据覆盖删除
	while (pos <= ps->size)
	{
		ps->a[pos] = ps->a[pos + 1];
		pos++;
	}
	--ps->size;
}

有了在指定位置插入和删除前提下,头插,头删,尾插,尾删新写法

头插,头删,尾插,尾删新写法

cpp 复制代码
//头插
void SeqListPushFront(SeqList* ps, ElemType x)
{
	SeqListInsert(ps, 0, x);
}
//头删
void SeqListPopFront(SeqList* ps)
{
	SeqListErase(ps, 0);
}
//尾插
void SeqListPushBack(SeqList* ps, ElemType x)
{
	SeqListInsert(ps, ps->size,x);
}
//尾删
void SeqListPopBack(SeqList* ps)
{
	SeqListErase(ps, ps->size);
}

打印顺序表

cpp 复制代码
void SeqListprintf(SeqList* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

销毁顺序表

动态开辟的内存需要我们主动去释放空间 这里需要主动free

cpp 复制代码
void DestroyedSeqList(SeqList* ps)
{
	free(ps->a);
	ps->a == NULL;
	ps->capacity = ps->size = 0;
}
相关推荐
小鱼在乎5 分钟前
动态规划---最长回文子序列
算法·动态规划
jimmy.hua6 分钟前
C++刷怪笼(5)内存管理
开发语言·数据结构·c++
xiaobai12 39 分钟前
二叉树的遍历【C++】
开发语言·c++·算法
Freak嵌入式16 分钟前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
java·开发语言·数据结构·python·接口·抽象基类
吱吱鼠叔34 分钟前
MATLAB数学规划:2.线性规划
算法·机器学习·matlab
声学黑洞仿真工作室41 分钟前
Matlab Delany-Bazley和Miki模型预测多孔材料吸声性能
开发语言·人工智能·算法·matlab·微信公众平台
机器学习之心1 小时前
选址模型 | 基于混沌模拟退火粒子群优化算法的电动汽车充电站选址与定容(Matlab)
算法·选址模型
MogulNemenis1 小时前
力扣春招100题——队列
数据结构·算法·leetcode
码上一元1 小时前
【百日算法计划】:每日一题,见证成长(017)
java·算法
学java的小菜鸟啊1 小时前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp