数据结构(1)--顺序表

这是写给自己以后复习看的,把重要的记下来

目前我已经学完了栈和队列,对数据结构已经有了一定的理解,相比于C语言,我认为数据结构其实没有"新知识",它的真面目是运用C语言学的,数组,函数,指针,结构体,动态内存管理等知识来做一些结构,从而更好地解决一些问题。

一.什么是顺序表?

所谓顺序表,有点像数组,但不完全是

**定义:**一段物理地址连续的存储单元,依次存储数据的线性结构。

二.核心特征

特征就很符合线性规律:

  1. 物理连续:内存地址相邻,无空隙。

  2. 逻辑有序:存储顺序与逻辑顺序一致。

不论是物理上还是逻辑上,顺序表都是线性的。

顺序表也分为动态顺序表和静态顺序表,通常都是用动态,因为静态顺序表申请的空间是固定的,不能扩容,申请空间小了会溢出,申请多了又会浪费空间。

三.基本结构

复制代码
//动态顺序表
typedef struct SeqList 
{
	SLDataType* arr;//动态数组,用于储存数据
	int size;//用来表示顺序表长度
	int capacity;//空间大小
}SL;

基本结构就长这样了,其中的SLDataType是方便改数据类型的。

接下来就是重头戏了。

四.关于顺序表的操作

复制代码
void SLInit(SL*ps);//顺序表初始化

void SLDestroy(SL* ps);//顺序表销毁

void SLpushback(SL* ps, SLDataType x);//顺序表尾插

void SLpushfront(SL* ps, SLDataType x);//顺序表头插

void SLpopback(SL* ps);//顺序表尾删

void SLpopfront(SL* ps);//顺序表头删

void SLInsert(SL* ps, int pos, SLDataType x);//顺序表指定位置插入

void SLErase(SL* ps, int pos);//顺序表指定位置删除

我写了这么多操作,说实话刚开始学还是有点痛苦的,有点懵逼,不过现在好多了。

一个个来介绍吗?我把对应的代写出来吧。

1.初始化

cpp 复制代码
void SLInit(SL* ps)//初始化
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

很简单,没啥好说的。

2.销毁

cpp 复制代码
void SLDestroy(SL* ps)//销毁
{
	assert(ps);
	free(ps->arr);
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

简单来说就是该置零的置零,该置空的置空。

3.尾插

cpp 复制代码
void SLpushback(SL* ps, SLDataType x)//尾插
{
	
		assert(ps);//检查空指针
	
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* temp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (temp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->arr = temp;
		ps->capacity = newcapacity;
		
	}
ps->arr[ps->size++] = x;
}

尾插是我感觉最难的步骤了,这个解决了就好理解多了。

我们先看最后一句:

cpp 复制代码
ps->arr[ps->size++] = x;

这其实才是插入,前面的部分是检查容量外加扩容。这一步是先插入,再让size++;

重点是扩容部分。

cpp 复制代码
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;

这一步是判断初始容量,如果为0,就直接让新空间==4,如果不是0,那就2倍扩容(当然前提是if的条件------ps->size == ps->capacity)

cpp 复制代码
SLDataType* temp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
if (temp == NULL)
{
	perror("realloc fail");
	return;
}
ps->arr = temp;
ps->capacity = newcapacity;

切记,刚才那个步骤只是改变了capacity的值,并没有实际开辟新空间,这一步就是配合newcapacity 来扩容arr的,这样就好理解了。

这样我们就知道了,尾插就是就是 容量检查(扩容)+插入(size++)

这样就可以把前面那和检查扩容部分单独写成一个函数:

cpp 复制代码
void  SLCheckCapacity(SL*ps)
{
	assert(ps);

	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* temp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));
		if (temp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->arr = temp;
		ps->capacity = newcapacity;

	}
}

这样代码就可以简化了,比如接下来的头插:

cpp 复制代码
void SLpushfront(SL* ps, SLDataType x)//头插
{
	assert(ps);
	SLCheckCapacity(ps);//检查扩容部分写成函数
	for (int i = ps->size;i > 0;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}

头插这个循环开始可能会很绕,其实我现在看到都觉得绕了点,它是让数据一个个后移,比如

arr[4]=arr[3],arr[3]=arr[2]......arr[1]=arr[0];

不太好讲,稍微想一下就知道在后移动了,这样吧arr[0]空出来,就可以插入进去了。

记住让size++.

4.尾删

cpp 复制代码
void SLpopback(SL*ps)//尾删
{
	assert(ps);
	assert(ps->size);
	--ps->size;
}

很简单,没啥好说的

5.头删

cpp 复制代码
void SLpopfront(SL* ps)//头删
{
	assert(ps);
	assert(ps->size);
	for (int i = 0;i<ps->size-1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

头删也简单,细想一下就明白了。

6.指定位置插入

cpp 复制代码
void SLInsert(SL* ps, int pos, SLDataType x)//指定位置插入
{
	SLCheckCapacity(ps);
	assert(pos >= 0 && pos <= ps->size);
	for (int i = ps->size;i > pos;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

通过循环把数据往后移动,让pos空出来,从而插入数据。

7.指定位置删除

cpp 复制代码
void SLErase(SL* ps, int pos)//指定位置删除
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos;i < ps->size - 1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

比较简单,还行。

好了,总共就这样了,以后复习应该很容易看懂了

相关推荐
阿阳微客1 小时前
CS2饰品市场急跌,抄底时机是否已到?
笔记·学习·游戏
gz927cool1 小时前
【系统架构】可观测性设计及其应用——面向智能体开发视角
人工智能·学习·ai·系统架构
爱编码的小八嘎1 小时前
C语言完美演绎9-24
c语言
牢姐与蒯1 小时前
c++数据结构之AVL树
数据结构
小娄~~1 小时前
多线程函数
c语言·开发语言
星幻元宇VR2 小时前
5D球幕飞行影院|沉浸式科技体验引领文旅与科普新方向
科技·学习·安全·虚拟现实
南境十里·墨染春水2 小时前
linux 学习进展 mysql 事务详解
linux·学习·mysql
博界IT精灵2 小时前
图的存储结构(哈喜老师版本)
数据结构·考研
星空语2 小时前
音频Kernel+HAL层学习规划
学习·音视频