【探索数据结构】线性表之顺序表

🎉🎉🎉欢迎莅临我的博客空间,我是池央,一个对C++和数据结构怀有无限热忱的探索者。🙌

🌸🌸🌸这里是我分享C/C++编程、数据结构应用的乐园✨

🎈🎈🎈期待与你一同在编程的海洋中遨游,探索未知的技术奥秘💞

📝专栏指路:

📘【C++】专栏:深入解析C++的奥秘,分享编程技巧与实践。

📘【数据结构】专栏:探索数据结构的魅力,助你提升编程能力。

前言

初步认识了数据结构后,我们一起来探索它的逻辑结构里面的线性结构吧。线性结构是一对一的关系。线性表在逻辑结构上是连续的,在物理结构上不一定是连续的。线性表中的顺序表(本篇的主角)在物理结构上是连续的,而线性表中的链表在物理结构上却是不连续的。

一、线性表

线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,其中n为表长,当n=0时线性表是一个空表。

几个概念:

1.ai是线性表中的“第i个”元素线性表中的位序(位序从1开始,注意区分数组下标从0开始

2.a1是表头元素;an是表尾元素。

3.除第一个元素外,每个元素有且仅有一个直接前驱(前一个元素);除最后一个元素外,每个元素有且仅有一个直接后继(后一个元素)

9d59d7f954594b72b79f785bc43c8078.png

二、顺序表

正片开始!

1.概念

顺序表——用顺序存储的方式实现线性表顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。顺序表的底层是数组。

9d44e91b48c64bed94713f95e628031c.jpg

2.静态顺序表

顺序表的空间大小固定

补充:为了简化代码,我们使用typedef 重命名自定义类型,typedef的优势是什么?

在C或C++中,typedef 关键字用于为已存在的数据类型定义一个新名称(别名)。这在需要简化复杂的数据类型声明,或者为特定的数据类型提供一个更有描述性的名称时非常有用。

代码如下:

typedef int SQLDataType;//顺序表的数据类型
//静态顺序表
typedef struct SeqList
{
	SQLDataType arr[100];
	int size;//有效数据个数
	int capacity;//空间大小
}SL;

3.动态顺序表

顺序表的大小空间不固定,可根据需求改变。

当顺序表存满时,用realloc增容。

typedef int SQLDataType;//顺序表的数据类型
//动态顺序表
typedef struct SeqList
{
	SQLDataType* arr;
	int size;//有效数据个数
	int capacity;//空间大小
}SL;

补充:realloc扩容的规则是什么?

一次扩充一个空间 ,插入一个元素还不会造成空间浪费程序(执行效率低下)

一次扩容固定个大小的空间(10、100…)【小了造成频繁扩容】【大了造成空间浪费】

最优解:成倍数的增加(1.5倍、2倍),数据插入的越多扩容的大小越来越大

扩容后会自动把原有空间释放掉

82685d545a784ea69d837396cae09657.png

malloc,realloc,calloc三者区别是什么?

  • malloc函数:用于动态分配指定字节数的内存空间,并返回一个指向它的指针。如果分配成功,则返回非空指针;如果内存空间不足,则返回NULL。需要注意的是,malloc分配的内存空间并未初始化,它们的值是未知的。
  • calloc函数:也用于动态分配内存空间,与malloc有所不同。calloc在分配内存空间时,会将其初始化为0。它的参数是要分配的元素个数和每个元素的大小,而不是总的字节数。如果分配成功,则返回指向分配的内存的指针;如果失败,则返回NULL。
  • realloc函数:用于调整之前分配的内存空间大小。它接收一个指向已分配内存的指针和一个新的大小,然后尝试调整内存块的大小。如果成功,则返回指向新的内存块的指针;如果失败,则返回NULL,而原来的内存块保持不变。

代码示例

//是否需要申请空间
void SQLcapacity(SL* ps)
{
	if (ps->capacity == ps->size)//空间已满,需要申请空间
	{
		//realloc增容,一般增加成原本空间大小的二或三倍
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SQLDataType* tmp = (SQLDataType*)realloc(ps->arr, newcapacity * sizeof(SQLDataType));
		if (tmp == NULL)
		{
			perror("reacoll fail!");//空间申请失败
			exit(1);//退出程序
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

4.对顺序表的操作

(1)初始化

void InitSql(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

(2)尾插

d934bfbb346e4a638f70d2beca95b97c.png

void PushBackSql(SL* ps, SQLDataType x)
{
	assert(ps);
	//插入之前先看空间够不够
	SQLcapacity(ps);
	ps->arr[ps->size++] = x;//size是顺序表尾部,后置++插入x后size加一
}

(3)头插

124e19006b51471aaab9c905f9ade1b9.png

//头部插入
void PushHeadSql(SL* ps, SQLDataType x)
{
	assert(ps);
	//插入之前先看空间够不够
	SQLcapacity(ps);
	//让原本的数据往后移一位
	for (int i = ps->size;i > 0;i--)
	{
		ps->arr[i] = ps->arr[i - 1];//arr[1]=arr[0]让arr[1]的位置放入原本arr[0]的数据
	}
	ps->arr[0] = x;
	ps->size++;
}

(4)查找

//查找指定数据
int FindPosSql(SL* ps, SQLDataType x)
{
	assert(ps);
	for (int i = 0;i < ps->size;i++)
	{
		if (ps->arr[i] == x)
			return i;
	}
	return -1;
}

找到了返回下标,找不到则返回不存在的下标

(5)尾删

//尾部删除
void DelBackSql(SL* ps)
{
	assert(ps);
	assert(ps->size);//顺序表为空时不能执行删除操作
	ps->size--;
}

(6)头删

b688a74378ed4dc88226fa9a969ee07a.png

//头部删除
void DelHeadSql(SL* ps)
{
	assert(ps);
	assert(ps->size);//顺序表为空时不能执行删除操作
	//顺序表存放数据整体往前挪一位
	for (int i = 0;i < (ps->size) - 1;i++)
	{
		//arr[0]的位置放原本arr[1]的数据,最后是ps->arr[size-2]=ps->arr[size-1]
		ps->arr[i] = ps->arr[i + 1];//arr[0]的位置放原本arr[1]的数据,最后是ps->arr[size-2]=ps->arr[size-1]
	}
	ps->size--;
}

(7)在指定位置之前插入数据

89b960a539204d2c8b747945b29a0b28.png

//指定位置前插入
void AddPosSql(SL* ps, int pos, SQLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//先看看空间够不够
	SQLcapacity(ps);
	//pos位置上的数和他后面的数整体往后挪一位
	for (int i = ps->size;i > pos;i--)
	{
		ps->arr[i] = ps->arr[i - 1];//结束arr[pos+1]=arr[pos];
	}
	ps->arr[pos] = x;
	ps->size++;
}

(8)在指定位置删除数据

38e8eb6590294644a348f55083f5ab38.png

//删除指定位置数据
void DelPosSql(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];//arr[size-2]=arr[size-1]
	}
	ps->size--;
}

(9)销毁

//销毁顺序表
void DestroySql(SL* ps)
{
	if (ps->arr)//不是空表才需要释放
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

顺序表小结

a13c2e0f17464d7abd5d2d6220e6a887.png

下一篇预告:线性表之单链表

持续更新中...

敬请期待

  • 61
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值