重生之我在异世界学编程之算法与数据结构:深入静态顺序表篇

重生之我在异世界学编程之算法与数据结构:深入静态顺序表篇
大家好,这里是小编的博客频道
小编的博客:就爱学编程
很高兴在ZEEKLOG这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!

本文目录

引言

C语言顺序表(Sequential List)是一种线性表的存储结构,采用一段地址连续的存储空间来依次存放线性表的元素。其特点是逻辑上相邻的元素在物理位置上也相邻,可以通过下标直接访问任意位置的元素,因此具有高效的随机存取性能。顺序表通常使用数组来实现,并配备一个变量来记录当前表的长度。其主要操作包括初始化、插入、删除、查找和遍历等。由于需要预先分配固定大小的内存空间,顺序表在插入和删除元素时可能会遇到内存重新分配的问题,但在已知数据规模或元素变动不频繁的情况下,顺序表仍是一种高效且易于实现的数据结构。那现在,一起来看看吧!!!

在这里插入图片描述

那接下来就让我们开始遨游在知识的海洋!

正文


一、顺序表的概念及结构

1. 顺序表的定义

顺序表是用一段地址连续的存储单元依次存储线性表的数据元素的线性表。其特点是逻辑上相邻的元素在物理位置上也相邻。顺序表一般使用数组来实现。

2. 顺序表的结构

顺序表的基本结构包括一个用于存储数据元素的数组和一个表示当前顺序表长度的变量(通常称为“长度”或“size”)。此外,为了操作的方便和高效,有时还需要设置一个“最大容量”(通常称为“capacity”)来表示顺序表可以容纳的最大元素个数。

如下所示:

#defineMAXSIZE100// 定义顺序表的最大容量typedefint ElemType;// 定义顺序表中存储的数据类型typedefstruct{ ElemType data[MAXSIZE];// 存储数据元素的数组int length;// 当前顺序表的长度} SqList;
  • 在上述结构中,data是一个一维数组,用于存放顺序表中的元素;length是一个整型变量,用于记录顺序表中当前所含元素的个数。

3. 顺序表的初始化

顺序表的初始化操作主要是设置其长度为0,并可以根据需要为其分配存储空间(如果采用动态分配的话)。

以下是一个简单的初始化函数示例:

voidInitList(SqList *L){ L->length =0;// 将顺序表的长度初始化为0}

注意:

  • 这里我们假设顺序表的存储空间已经通过定义结构体时分配的数组来实现了,因此不需要额外的内存分配操作。如果需要动态分配存储空间,则需要在初始化函数中调用相应的内存分配函数(如malloc)来为data数组分配内存。

二、顺序表的基本操作(静态)

1. 插入操作

在顺序表中插入一个新元素时,需要找到插入位置,然后将该位置及其后的所有元素都向后移动一位,最后将新元素放入指定位置。插入操作的时间复杂度为O(n),其中n是顺序表的长度。

以下是插入操作的实现代码:

#include<stdio.h>#include<stdbool.h> bool ListInsert(SqList *L,int i, ElemType e){if(i <1|| i > L->length +1){return false;// 插入位置不合法}if(L->length >= MAXSIZE){return false;// 顺序表已满,无法插入新元素}for(int k = L->length -1; k >= i -1; k--){ L->data[k +1]= L->data[k];// 将插入位置及其后的元素后移一位} L->data[i -1]= e;// 在指定位置插入新元素 L->length++;// 顺序表长度加1return true;}
  • 在上述代码中,我们首先检查插入位置是否合法以及顺序表是否已经满员。然后,从顺序表的末尾开始向前遍历,将插入位置及其后的所有元素都向后移动一位。最后,在指定位置插入新元素,并将顺序表的长度加1

2. 删除操作

在顺序表中删除一个元素时,需要找到要删除的元素的位置,然后将该位置之后的所有元素都向前移动一位。删除操作的时间复杂度也为O(n)。

以下是删除操作的实现代码:

bool ListDelete(SqList *L,int i, ElemType *e){if(i <1|| i > L->length){return false;// 删除位置不合法}*e = L->data[i -1];// 保存被删除的元素的值for(int k = i; k < L->length; k++){ L->data[k -1]= L->data[k];// 将删除位置之后的元素前移一位} L->length--;// 顺序表长度减1return true;}
  • 在上述代码中,我们首先检查删除位置是否合法。然后,将要删除的元素的值保存到参数e指向的变量中。接着,从删除位置开始向后遍历,将删除位置之后的所有元素都向前移动一位。最后,将顺序表的长度减1

3. 查找操作

在顺序表中查找一个元素时,需要从头到尾依次比较每个元素与目标值的大小关系,直到找到目标值或者遍历完整个顺序表为止。查找操作的时间复杂度为O(n)。

以下是按值查找操作的实现代码:

intLocateElem(SqList L, ElemType e){for(int i =0; i < L.length; i++){if(L.data[i]== e){return i +1;// 返回查找到的元素的位序(从1开始计数)}}return0;// 未找到目标元素,返回0或其他特殊标记值}
  • 在上述代码中,我们使用了一个循环来遍历顺序表中的每个元素,并将其与目标值进行比较。如果找到了目标值,则返回其在顺序表中的位序(从1开始计数);否则,返回0或其他特殊标记值来表示未找到目标元素

另外,还可以根据元素的位序来查找对应的元素值。这种操作的时间复杂度也是O(1)(因为可以直接通过下标访问),但前提是已知元素的位序且该位序在顺序表的范围内内有效


4. 更新操作

更新操作是指修改顺序表中某个位置的元素的值。由于顺序表是基于数组的实现的,因此可以通过直接访问数组的下标来快速定位并修改指定位置的元素的值。更新操作的时间复杂度为O(1)。

以下是更新操作的实现代码:

bool ListUpdate(SqList *L,int i, ElemType e){if(i <1|| i > L->length){return false;// 修改位置不合法} L->data[i -1]= e;// 修改指定位置的元素的值return true;}
  • 在上述代码中,我们首先检查修改位置是否合法。然后,直接通过下标访问并修改指定位置的元素的值。

5. 获取元素操作

获取元素操作是指获取顺序表中某个位置的元素的值。与更新操作类似,由于顺序表是基于数组的实现的,因此可以通过直接访问数组的下标来快速获取指定位置的元素的值。获取元素操作的时间复杂度也为O(1)。

以下是获取元素操作的实现代码:

bool GetElem(SqList L,int i, ElemType *e){if(i <1|| i > L.length){return false;// 获取位置不合法}*e = L.data[i -1];// 获取指定位置的元素的值return true;}
  • 在上述代码中,我们首先检查获取位置是否合法。然后,直接通过下标访问并获取指定位置的元素的值,并将其保存到参数e指向的变量中。

6. 遍历操作

遍历操作是指依次访问顺序表中的每个元素,并对它们进行某种处理(如打印输出)。遍历操作可以使用循环语句来实现,时间复杂度为O(n)。

以下是遍历操作的实现代码:

voidTraverseList(SqList L){for(int i =0; i < L.length; i++){printf("%d ", L.data[i]);// 打印输出每个元素的值(假设元素类型为整型)}printf(" ");}
  • 在上述代码中,我们使用了一个循环来遍历顺序表中的每个元素,并使用printf函数将其打印输出。当然,在实际应用中,对元素的处理方式可能更加复杂多样。

7. 求顺序表的长度

求顺序表的长度操作是指获取顺序表中当前所含元素的个数。由于顺序表的长度是通过一个整型变量来记录的,因此该操作的时间复杂度为O(1)。

以下是求顺序表长度的实现代码:

intListLength(SqList L){return L.length;// 返回顺序表的长度}
  • 在上述代码中,我们直接返回了顺序表的长度变量的值。

8. 判断顺序表是否为空

判断顺序表是否为空操作是指检查顺序表中是否包含任何元素。这可以通过比较顺序表的长度与0的大小关系来实现,时间复杂度为O(1)。

以下是判断顺序表是否为空的实现代码:

bool IsEmpty(SqList L){return L.length ==0;// 如果顺序表的长度为0,则表示为空表}
  • 在上述代码中,我们比较了顺序表的长度与0的大小关系,并根据结果返回一个布尔值来表示顺序表是否为空。

快乐的时光总是短暂,咱们下篇博文再见啦!!!在下一篇博文,小编将会带着宝子们学习动态顺序表,敬请期待吧!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!

Read more

coding ability 展开第六幕(前缀和算法——一维到二维)超详细!!!!

coding ability 展开第六幕(前缀和算法——一维到二维)超详细!!!!

文章目录 * 前言 * 前缀和 * 寻找数组的中心下标 * 思路 * 除自身以外数组的乘积 * 思路 * 总结 * 总结 前言 本专栏上一篇已经把二分查找的习题结束啦 其实核心就是找出二段性,然后找出判断条件,然后选板子二分即可 今天我们来学习新的算法知识,前缀和 关于前缀和,可能大家在蓝桥杯或者一些算法比赛都听过 其实前缀和不难的,跟我一起来看看吧 前缀和 前缀和(Prefix Sum)是一种预处理数组的方法,通过构建一个辅助数组 s,使得 s[i] 表示原数组 a 前 i 个元素的和(索引从 0 到 i-1或者 0 到 i)。 核心作用:快速计算任意区间 [l, r] 的和,时间复杂度为 O(1)

By Ne0inhk
【OpenClaw从入门到精通】第04篇:Web/TUI/钉钉全打通!OpenClaw多端交互实测指南(2026避坑版)

【OpenClaw从入门到精通】第04篇:Web/TUI/钉钉全打通!OpenClaw多端交互实测指南(2026避坑版)

摘要:本文聚焦OpenClaw三大核心交互方式,针对新手“不知如何与AI助理沟通”的痛点,提供Web控制台、TUI终端、聊天软件(以钉钉为核心)的完整实操流程。Web控制台适配电脑端深度配置,TUI终端适合服务器远程维护,聊天软件满足手机端移动办公,三者协同实现“随时随地召唤AI”。文中包含2026实测的命令代码、配置步骤、问题排查方案,所有案例为虚拟构建,代码未上传GitHub,兼顾新手入门与进阶实操,帮助读者快速打通多端交互,最大化OpenClaw使用效率。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:高并发+性能调优终极实战】【Coze搞钱实战:零代码打造吸金AI助手】

By Ne0inhk
进阶数据结构: AVL树

进阶数据结构: AVL树

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let's go! 我的博客:yuanManGan 我的专栏:C++入门小馆 C言雅韵集 数据结构漫游记  闲言碎语小记坊 题山采玉 领略算法真谛 目录 AVL相关概念:  AVL树的结构 Insert  旋转 右旋: 编辑 左单旋:  右左双旋: 左右双旋:  完整的插入: 其他简单的操作:  测试: AVL相关概念: AVL树是由二叉搜索树加上一定的限制而形成的树,AVL树:它的左右子树都是AVL树,且左右子树的高度差的绝对值不超过1。AVL树是⼀颗⾼度平衡搜索⼆叉树, 通过控制⾼度差去控制平衡。

By Ne0inhk
C++ 核心数据结构:Stack 与 Queue 类深度解析

C++ 核心数据结构:Stack 与 Queue 类深度解析

🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟     目录 💯前言 💯Stack 类 (一)Stack 类的概念与特点 (二)Stack 类的使用 (三)Stack 类的内部实现(手动实现) (四)Stack 类的应用场景 💯Queue 类 (一)Queue 类的概念与特点 (二)Queue 类的使用 (三)Queue 类的内部实现(手动实现) (四)Queue 类的应用场景 💯总结 💯前言 在 C++ 编程领域,数据结构的合理运用是构建高效、可靠程序的关键因素之一。Stack(栈)和 Queue(队列)作为两种基础且重要的数据结构,

By Ne0inhk