数据结构 之 【顺序表实现】(c语言实现)

server/2025/2/25 18:01:02/

强烈建议看完上一期博客之后再来看这一期

数据结构之【顺序表简介】

3.实现顺序表的增删查改

静态顺序表的缺陷较大,

所以下面展示的是动态顺序表的相关函数

3.1初始化

结构体变量创建之后,首先初始化一下才好

#define INIT_CAPACITY 10
void SLINIT(SL* ps)
{assert(ps);ps->arr = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);ps->capacity = INIT_CAPACITY;ps->size = 0;
}

1.传入的指针不能为空时

为了节约调试时间,断言一下

2.初始化的时候,入的是结构体的地址

因为

传址传参,才能根据地址改变相应的值

传值传参,会导致“形参改变,实参不变”的情况

传值传参时,形参是实参的临时拷贝

3.2销毁顺序表

动态开辟部分内存

当不再使用的时候,需要程序员主动释放

void SLDestroy(SL* ps)
{assert(ps);free(ps->arr);ps->capacity = 0;ps->size = 0;
}

1.传入的指针不能为空时

为了节约调试时间,断言一下

2.销毁的时候,入的是结构体的地址

因为

传址传参,才能根据地址改变相应的值

传值传参,会导致“形参改变,实参不变”的情况

传值传参时,形参是实参的临时拷贝

3.3打印顺序表

编写这个函数之后

有利于我们调试自己的程序

void SLPrint(SL* ps)
{assert(ps);//每个数据元素之后有空格for (int i = 0; i < ps->size; ++i){printf("%d ", ps->arr[i]);}//打印完一行就换行print("\n");
}

(1)打印的时候,入的是结构体的地址

因为

尽管传值与传址传参都可以实现打印的功能

但是传值传参会拷贝结构体的内容

如果结构体太大,可能会导致栈溢出等现象

而传址传参则不会有这种可能

(2)传入的指针不能为空时

为了节约调试时间,断言一下

3.4顺序表扩容

有效数据个数与空间容量相等的时候

就可以考虑扩容

void CheckCapacity(SL* ps)
{assert(ps);if (ps->capacity == ps->size){ps->capacity *= 2;SLDataType* temp = (SLDataType*)realloc(ps->arr, sizeof(SLDataType) * (ps->capacity));if (temp == NULL)return;ps->arr = temp;}
}

(1).扩容的时候,入的是结构体的地址

因为

传址传参,才能根据地址改变相应的值

传值传参,会导致“形参改变,实参不变”的情况

传值传参时,形参是实参的临时拷贝

 (2).传入的指针不能为空时

为了节约调试时间,断言一下

(3).realloc 扩容可能会出现 异地扩容 的情况

所以需要将扩容成功的新指针temp赋值给结构体中的指针arr

(4)扩容时,一般扩充到原来的两倍就可以了

3.5增删查改 之【头插】

头插的意思就是将数据插入到顺序表的最前面

void PushFront(SL* ps, SLDataType x)
{//检查是否为空assert(ps);//检查是否需要扩容CheckCapacity(ps);//实现头插int end = ps->size - 1;while (end >= 0){(ps->arr)[end + 1] = (ps->arr)[end];end--;}(ps->arr)[0] = x;(ps->size)++;
}

(1)头插的时候,入的是结构体的地址

因为

传址传参,才能根据地址改变相应的值

传值传参,会导致“形参改变,实参不变”的情况

传值传参时,形参是实参的临时拷贝

(2)传入的指针不能为空时

为了节约调试时间,断言一下

(3)为了防止越界访问,即空间不够的情况

检查空间容量

(4)从后往前遍历整个数组,

将数据从前往后移动一个单元

这样就可以空出 头 的位置

(5)注意有效数据个数要改变

3.6增删查改 之【头删】

头删的意思就是顺序表最前面的数据删除

void PopFront(SL* ps)
{//检查为空assert(ps);//检查有效数据个数assert(ps->size > 0);//实现头删int begin = 1;while (begin < ps->size){(ps->arr)[begin - 1] = (ps->arr)[begin];++begin;}(ps->size)--;
}

(1)头删的时候,入的是结构体的地址

因为

传址传参,才能根据地址改变相应的值

传值传参,会导致“形参改变,实参不变”的情况

传值传参时,形参是实参的临时拷贝

(2) 传入的指针不能为空时

为了节约调试时间,断言一下

(3) 顺序表中必须要有数据

ps->size > 0

才能进行删除操作

不然会出现未定义行为

(4) 从前往后遍历整个数组,

将数据从后往前移动一个单元

(5) 注意有效数据个数要改变

 3.7增删查改 之【尾插】

尾插的意思就是将数据插入到顺序表的最后面

void PushBack(SL* ps, SLDataType x)
{//检查是否为空assert(ps);//检查是否需要扩容CheckCapacity(ps);//实现尾插(ps->arr)[ps->size] = x;(ps->size)++;
}

(1)有效数据个数 ps->size 正好是顺序表最后面的下标

(2)注意)有效数据个数变化

3.8增删查改 之【尾删】

尾删的意思就是顺序表最后面的数据删除

void PopBack(SL* ps)
{//检查为空assert(ps);//检查有效数据个数assert(ps->size > 0);//实现尾删(ps->size)--;
}

(1)让有效数据个数直接减一即可

直接不访问就好了

有效数据个数为0,插入N个数据时,

头插的时间复杂度:O(N^2)

尾插的时间复杂度:O(N)

有效数据个数为N,删除N个数据时,

头删的时间复杂度:O(N^2)

尾删的时间复杂度:O(1)

 3.9增删查改 之【有效范围内插入】

有效范围内插入的意思就是将数据插入到顺序表当中

0<= 下标 <= (ps->size)

这样,

头插尾插也包含在内了

void Insert(SL* ps, int pos, SLDataType x)
{//检查是否为空assert(ps);//检查下标位置assert(pos >= 0 && pos <= ps->size);//检查是否需要扩容CheckCapacity(ps);//实现插入int end = ps->size - 1;while (end >= pos){(ps->arr)[end + 1] = (ps->arr)[end];--end;}(ps->arr)[pos] = x;(ps->size)++;
}

(1)从后往前遍历,实现移动即可

 3.10增删查改 之【有效范围内删除】

有效范围内删除的意思就是顺序表当中的数据删除

0<= 下标 <= (ps->size - 1)

这样,

头删尾删也包含在内了

void Erase(SL* ps, int pos)
{//检查为空assert(ps);//检查下标位置assert(pos >= 0 && pos < ps->size);//实现删除int begin = pos + 1;while (begin < ps->size){ps->arr[begin - 1] = ps->arr[begin];++begin;}ps->size--;
}

(1)注意下标位置的范围

(2)从前向后遍历,从后向前移动

 这样,你只需要写

Insert 和 Erase 两个函数

就可以实现头删尾删头插尾插等

 3.11增删查改 之【有效范围内查找】

 有效范围内查找的意思就是顺序表当中查找想要的值

没有技巧可言,直接暴力查找就好

int Find(SL* ps, SLDataType x)
{for (int i = 0; i < ps->size; ++i){if (ps->arr[i] == x)return i;}return -1;
}

http://www.ppmy.cn/server/170592.html

相关文章

SpringBoot五:Web开发

精心整理了最新的面试资料&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 要解决的问题 导入静态资源首页jsp&#xff0c;模板引擎Thymeleaf装配扩展SpringMVC增删改查拦截器国际化&#xff08;非重点&#xff09; 可以使用以下方式处理静态…

Plantsimulation中机器人怎么通过阻塞角度设置旋转135°

创建一个这样的简单模型。 检查PickAndPlace的角度表。源位于180的角位置&#xff0c;而物料终结位于90的角位置。“返回默认位置”选项未被勾选。源每分钟生成一个零件。启动模拟时&#xff0c;Plant Simulation会选择两个位置之间的最短路径。示例中的机器人无法绕135的角位…

hydra docker版本

最近做ssh暴力破解实验&#xff0c;由于服务器上面软件依赖太乱了&#xff0c;导致我花了好久没能成功编译出hydra&#xff0c;于是想到了使用docker版本的hydra&#xff0c;最后成功的完成了ssh暴力破解实验&#xff5e; ailx10 1958 次咨询 网络安全优秀回答者 互联网行业…

计算机毕业设计SpringBoot+Vue.js在线教育系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Maven最新版安装教程

一、Maven下载 1.前往官网下载 点击前往官网 2.进去之后点击Download 如果是Windows用户使用Maven则选择apache-maven-x.x.x-bin.zip即可。Liunx和MacOS用户则选择apache-maven-x.x.x-bin.tar.zip。 由于服务器在国外下载可能会很慢或者失败&#xff0c;大家可以去网盘获取 …

【备赛】点亮LED

LED部分的原理图 led前面有锁存器&#xff0c;这是为了防止led会受到lcd的干扰&#xff08;lcd也需要用到这些引脚&#xff09;。 每次想要对led操作&#xff0c;就需要先打开锁存器&#xff0c;再执行操作&#xff0c;最后关闭锁存器。 这里需要注意的是&#xff0c;引脚配置…

深度学习训练平台建设中的性能优化实践

在当今数据驱动的时代&#xff0c;深度学习已成为人工智能领域的关键技术。然而&#xff0c;深度学习的成功不仅依赖于算法的先进性&#xff0c;还极大地依赖于训练平台的性能和效率。本文将探讨深度学习训练平台建设中的性能优化实践&#xff0c;特别是在任务模板、数据处理、…

【linux】自主shell编写

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.输出命令行02.获取用户命令字符串03.命令行字符串分割04.执行命令05.细节修改检查是否为内建命令 完整代码&#xff1a; 01.输出命令行 完成对一个shell 的编写&#xff0c;首…