数据结构---顺序表

文章目录

线性表

线性表的定义

  • 线性表是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;
}
相关推荐
VertexGeek39 分钟前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz40 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
jiao_mrswang2 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca2 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱2 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子2 小时前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
是阿建吖!2 小时前
【优选算法】二分查找
c++·算法
王燕龙(大卫)2 小时前
leetcode 数组中第k个最大元素
算法·leetcode
不去幼儿园3 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Mr_Xuhhh3 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法