数据结构---顺序表

文章目录

线性表

线性表的定义

  • 线性表是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;
}
相关推荐
幸运超级加倍~26 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan2019031333 分钟前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法35 分钟前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR35 分钟前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer36 分钟前
快乐数算法
算法·leetcode·职场和发展
小芒果_0138 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_4340859039 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will39 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法
XuanRanDev42 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
gkdpjj43 分钟前
C++优选算法十 哈希表
c++·算法·散列表