大佬教程收集整理的这篇文章主要介绍了【数据结构】顺序表(增、删、查、改)的实现 [初阶篇_ 复习专用],大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
💛 前情提要💛
恭喜大家成功完成C语言@H_944_11@c;入门了这美丽的世界呀
本章节就开始进入数据结构@H_944_11@啦~
接下来我们即将进入一个全新的空间c;对代码有一个全新的视角~
以下的内容一定会让你对数据结构@H_944_11@有一个颠覆性的认识哦!!!
❗以下内容以C语言@H_944_11@的方式实现c;对于
数据结构@H_944_11@来说最重要的是
思想@H_944_11@哦❗
以下内容干货满满c;跟上步伐吧~
作者介绍:
🎓 作者: 热爱编程不起眼的小人物🐐 🔎作者的Gitee:代码仓库 Ὄc;系列文章&专栏推荐:
🐶《刷题特辑》—实现由小白至入门者的学习记录
😺C语言学习【小白->入门】_全过程_专栏
📒我和大家一样都是初次踏入这个美妙的“元”宇宙🌏 希望在输出知识的同时c;也能与大家共同进步、无限进步🌟
线性表&顺序表
顺序表接口的实现
顺序表的优缺点
线性表:是一种在实际中广泛使用的数据结构c;常见的线性表:顺序表、链表、栈、队列、字符串…
线性表:在逻辑@H_944_11@上是线性结构c;也就说是连续的一条直线。但是在
物理结构@H_944_11@上并不一定是连续的【线性表在
物理@H_944_11@上存储时c;通常以
数组@H_944_11@和
链式结构@H_944_11@的形式存储】
❗对于数据结构@H_944_11@,
C语言@H_944_11@提供了
结构体@H_944_11@类型给我们使用c;让我们更方便的整合一个结构c;去利用
结构体@H_944_11@实现数据结构
✨综上:就是线性表的概念啦~
➡️简单来说:线性表是一种常见的数据结构c;它在逻辑结构上呈连续直线结构c;但物理上就不一定是连续@H_944_11@的啦
💡概念及结构:
➡️简单来说:
顺序表可以理解为就是数组c;因为数组的元素存放c;在物理结构和逻辑结构上都是连续c;呈直线结构的
但有一点不同就是:顺序表之所以称为顺序表c;是因为里面的元素是按照顺序@H_944_11@存放的【而数组内可随意存放】
✨有了以上对顺序表@H_944_11@的概念后c;我们便可以实现它啦~
💡静态版: 即顺序表的空间大小不会随存储的数据个数而发生空间大小的变化【即固定的存储空间】
➡️简单来说: 使用定长数组@H_944_11@存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
@H_944_11@
👉由上述我们可知:
❗缺点: 不能在存储的过程中进行增容@H_944_11@
✨那么为了让我们的顺序表@H_944_11@更加灵活c;我们便可以将其写成
动态版@H_944_11@的
💡静态版: 即实现了对顺序表内空间进行动态的增长c;简称增容@H_944_11@
➡️简单来说: 使用动态开辟@H_944_11@的数组存储
Tips: 关于
动态开辟@H_944_11@不熟悉的同学可以跳转去🔍【C语言】动态内存管理 [进阶篇_ 复习专用]查看呀
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;
@H_944_11@
👉由上述我们可知:
基本实现和静态版没什么不同c;唯独将定长数组@H_944_11@c;改为可以接收动态开辟内存地址的
指针@H_944_11@c;且增加了一个变量
✨综上:
对于数据结构的接口实现c;一般围绕
增@H_944_11@、
删@H_944_11@、
查@H_944_11@、
改@H_944_11@的内容
💡如下的实现围绕此原码进行:
typedef int SeqDataType;
typedef struct SeqList
{
//int*a;
SeqDataType* a;
int size;
int capacity;
}SeqList, SEQ;
@H_944_11@
void TestSeqList1()
{
SeqList s;
}
int @H_911_612@main()
{
TestSeqList1();
//顺序表一般不要自己去动它
//而是交给函数去 初始化c;去操纵
return 0;
}
@H_944_11@
1️⃣初始化的函数声明:
void SeqLisTinit(SeqList* pq);
@H_944_11@
2️⃣初始化函数的实现:
void SeqLisTinit(SeqList* pq)
{
assert(pq);
pq-> a = NULL;
pq-> capacity = 0;
pq-> size = 0;
}
@H_944_11@
❗往后实现的接口都需要检查顺序表是否需要扩容@H_944_11@c;那我们便可以将其集成为一个函数c;方便后续调用
👉原理: 检查顺序表内的空间大小是否足够大
Ὂ5;特别注意:
一般增容的大小:以2倍进行增容
这样增下来不会导致增的太大c;从而浪费空间
1️⃣检查扩容的函数声明:
void SeqcheckCapacity(SeqList* pq);
@H_944_11@
2️⃣检查扩容函数的实现:
void SeqcheckCapacity(SeqList* pq)
{
//满了c;需要增容
if (pq->size == pq->capacity)
{
//通常 增容2倍
pq->capacity == 0 ? 4 : pq->capacity * 2;
int newcapacity = pq->capacity;
SeqDataType* newA = realloc(pq->a, sizeof(SeqDataType)*newcapacity);
if (newA == NULL)
{
printf("增容失败n");
}
exit(-1);
pq->a = newA;
pq->capacity = newcapacity;
}
}
@H_944_11@
👉简单来说: 对顺序表进行尾部插入数据
➡️实现: 直接访问顺序表的最后一个元素进行插入
1️⃣尾插的函数声明:
void SeqListPushBACk(SeqList* pq, SeqDataType x);
@H_944_11@
2️⃣尾插函数的实现:
void SeqListPushBACk(SeqList* pq, SeqDataType x)
{
assert(pq);
//检查空间大小
SeqcheckCapacity(pq);
pq->a[pq->size] = x;
pq->size++;
}
@H_944_11@
👉简单来说: 对顺序表进行头部插入数据
➡️实现: 需要将顺序表整体往后移动c;空出头部一个位置给插入
1️⃣头插的函数声明:
void SeqListPushFront(SeqList* pq, SeqDataType x);
@H_944_11@
2️⃣头插函数的实现:
void SeqListPushFront(SeqList* pq, SeqDataType x)
{
assert(pq);
SeqcheckCapacity(pq);
int end = pq->size - 1;
while (end >= 0)
{
pq->a[end + 1] = pq->a[end];
end--;
}
pq->a[0] = x;
pq->size++;
}
@H_944_11@
👉简单来说: 对顺序表进行删除最后一个数据
➡️实现: 直接将记录数组有效个数@H_944_11@的变量
size@H_944_11@减减即可c;这样就访问不到了
❗没必要对要删除的这个元素进行置空等等c;因为不影响【因为当后面如果尾插的话c;就会直接覆盖原来的数据了~】
Ὂ5;特别注意: 如果顺序表只剩下一个元素的时候c;就不能执行尾删@H_944_11@了
1️⃣尾删的函数声明:
void SeqListPopBACk(SeqList* pq);
@H_944_11@
2️⃣尾删函数的实现:
void SeqListPopBACk(SeqList* pq)
{
assert(pq);
assert(pq->size > 0);
pq->size--;
}
@H_944_11@
👉简单来说: 对顺序表进行删除第一个数据
➡️实现: 需要将顺序表整体前移数据c;覆盖第一位数据即达到删除的目的
Ὂ5;特别注意: 如果顺序表只剩下一个元素的时候c;就不能执行头删@H_944_11@了
1️⃣头删的函数声明:
void SeqListPopFront(SeqList* pq);
@H_944_11@
2️⃣头删函数的实现:
void SeqListPopFront(SeqList* pq)
{
assert(pq);
assert(pq->size > 0);
int begin = 0;
while (begin < pq->size - 1)
{
pq->a[begin] = pq->a[begin+1];
begin++;
}
pq->size--;
}
@H_944_11@
👉简单来说: 对顺序表进行查找所需的元素
➡️实现: 遍历顺序表一一比较查找是否有我们想要的元素
1️⃣查找元素的函数声明:
int SeqListFind(SeqList*pq, SeqDataType x);
@H_944_11@
2️⃣查找元素函数的实现:
int SeqListFind(SeqList*pq, SeqDataType x)
{
assert(pq);
for (int i = 0; i < pq->size; i++)
{
if (pq->a[i] == x)
{
return i;
//如果又 多个 xc;返回的是 优先找到的那个x的 下标
}
}
return -1;
}
@H_944_11@
👉简单来说: 对顺序表的某个位置的元素进行修改
➡️实现: 直接访问想要修改的元素的下标进行修改
Ὂ5;特别注意: 修改元素的下标要在顺序表有效个数的范围内
1️⃣修改元素的函数声明:
void SeqListModify(SeqList*pq, int pos, SeqDataType x);
@H_944_11@
2️⃣修改元素函数的实现:
void SeqListModify(SeqList*pq, int pos, SeqDataType x)
{
assert(pq);
assert(pos >= 0 && pos < pq->size);
pq->a[pos] = x;
}
@H_944_11@
👉简单来说: 对顺序表的某个位置前进行插入
➡️实现: 将从顺序表中要插入的位置开始c;往后原有的元素整体往后移动c;腾出空位来插入
Ὂ5;特别注意: 插入的位置要在顺序表有效个数的范围内
1️⃣任意位置插入元素的函数声明:
void SeqLisTinsert(SeqList*pq, int pos, SeqDataType x);
@H_944_11@
2️⃣任意位置插入元素函数的实现:
void SeqLisTinsert(SeqList*pq, int pos, SeqDataType x)
{
assert(pq);
aseert(pos > 0 && pos < pq->size);
//判断是否需要 扩容
SeqcheckCapacity(pq);
int end = pq->size - 1;
while (end >= pos)
{
pq->a[end+1] = pq->a[end];
end--;
}
}
@H_944_11@
💡有了任意位置插入元素函数@H_944_11@的实现c;我们的
头插@H_944_11@、
尾插@H_944_11@函数便可以复用这个函数来实现了
👉复用任意位置插入函数@H_944_11@的
头插函数@H_944_11@的实现:
void SeqListPushFront(SeqList* pq, SeqDataType x)
{
SeqLisTinsert(pq, x, 0);
}
@H_944_11@
👉复用任意位置插入函数@H_944_11@的
尾插函数@H_944_11@的实现:
void SeqListPushBACk(SeqList* pq, SeqDataType x)
{
SeqLisTinsert(pq, x,pq->size-1);
}
@H_944_11@
👉简单来说: 对顺序表的某个位置进行删除
➡️实现: 将从顺序表中要删除的元素开始c;往后所有的元素整体往前移动c;后面的元素覆盖要删除的位置的元素c;以达到删除@H_944_11@的目的
Ὂ5;特别注意: 删除的位置要在顺序表有效个数的范围内
1️⃣任意位置删除元素的函数声明:
void SeqListErase(SeqList*pq, int pos);
@H_944_11@
2️⃣任意位置删除元素函数的实现:
void SeqListErase(SeqList*pq, int pos)
{
assert(pq);
aseert(pos > 0 && pos < pq->size);
int begin = pos;
while (begin <= pq->size - 1)
{
pq->a[begin] = pq->a[begin + 1];
begin++;
}
pq->size--;
}
@H_944_11@
💡有了任意位置删除元素函数@H_944_11@的实现c;我们的
头删@H_944_11@、
尾删@H_944_11@函数便可以复用这个函数来实现了
👉复用任意位置删除函数@H_944_11@的
头删函数@H_944_11@的实现:
void SeqListPopFront(SeqList* pq)
{
SeqListErase(pq, 0);
}
@H_944_11@
👉复用任意位置删除函数@H_944_11@的
尾删函数@H_944_11@的实现:
void SeqListPopBACk(SeqList* pq)
{
SeqListErase(pq, pq->size - 1);
}
@H_944_11@
👉简单来说: 对顺序表进行组个打印
➡️实现: 遍历顺序表一一打印即可
1️⃣打印顺序表的函数声明:
void SeqListPrint(SeqList* pq);
@H_944_11@
2️⃣打印顺序表函数的实现:
void SeqListPrint(SeqList* pq)
{
assert(pq);
for (int i = 0; i < pq->size; i++)
{
printf("%d ", pq->a[i]);
}
printf("n");
}
@H_944_11@
👉简单来说: 对顺序表进行销毁c;释放内存空间
➡️实现: 直接将顺序表中的成员变量置为0@H_944_11@c;且释放顺序表的空间即可
1️⃣销毁顺序表的函数声明:
void SeqListDestory(SeqList* pq);
@H_944_11@
2️⃣销毁顺序表函数的实现:
void SeqListDestory(SeqList* pq)
{
assert(pq);
free(pq->a);
pq->a = NULL;
pq->capacity = pq->size = 0;
}
@H_944_11@
✨综上:就是顺序表接口实现的内容啦~
➡️相信大家对顺序表@H_944_11@有不一样的看法了吧🧡
ὓ5;优点:
随机访问@H_944_11@
🔴缺点:
综上c;我们基本了解了数据结构中的 “顺序表” 🍭 的知识啦~~
恭喜你的内功又双叒叕得到了提高!!!
感谢你们的阅读😆
✨如果觉得收获满满c;可以点点赞👍支持一下哟~✨
以上是大佬教程为你收集整理的【数据结构】顺序表(增、删、查、改)的实现 [初阶篇_ 复习专用]全部内容,希望文章能够帮你解决【数据结构】顺序表(增、删、查、改)的实现 [初阶篇_ 复习专用]所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。