【数据结构入坑指南(二.1)】--《数据结构与算法精讲:从数组到顺序表,如何让数据管理变得强大而优雅?》​​

【数据结构入坑指南(二.1)】--《数据结构与算法精讲:从数组到顺序表,如何让数据管理变得强大而优雅?》​​

🔥@晨非辰Tong:个人主页 

👀专栏:《C语言》《数据结构与算法》

💪学习阶段:C语言、数据结构与算法初学者

⏳“人理解迭代,神理解递归。”

引言:掌握了复杂度的衡量标尺,现在,让我们用它来审视第一个真正意义上的数据结构——顺序表。本文将亲手实现动态顺序表,并分析其各项操作的效率,为下一篇博客对顺序表的继续分享打通前路。

目录

一、线性表

二、顺序表

2.1  什么是顺序表?

2.2  顺序表类别

2.2.1  静态顺序表

2.2.2  动态顺序表

三、动态顺序表的实现(三文件协同)

SeqList.h

SeqList.c

test.c(测试文件)

四、动态顺序表的应用(初)

4.1  在尾部插入数据

 4.2  在头部插入数据


一、线性表

--线性表是n个有相同特性的数据元素的有限序列,是广泛应用的数据结构。常见的:顺序表、链表、栈、队列、字符串……

--线性表,逻辑上是线性结构(连续的一条线)。物理结构不一定是连续的,线性表在物理上存储,通常以顺序结构、链式结构存储。

二、顺序表

2.1  什么是顺序表?

--定义:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况采用数组存储。(顺序表底层是数组)

那顺序表就是数组?

--不!顺序表是对数组的封装,实现了常用的增删查改等接口。

--形象对比数组与顺序表:

2.2  顺序表类别

2.2.1  静态顺序表

--静态顺序表使用定长数组存储元素。

--不足:可能空间不够用,初始化给多有可能浪费。

--将 int 重新命名为 SLDataType

--size 指向有效数据的下一位;

2.2.2  动态顺序表

--动态顺序表的空间按需申请

--两种顺序表在不同的应用场景中各有作用。

三、动态顺序表的实现(三文件协同)

--实现动态顺序表,用以下三个文件:

SeqList.h

//SeqList.h头文件 #pragma once #include <stdio.h> #include <stdlib.h> //定义动态顺序表的结构 typedef int SLTDataType; typedef struct SeqList { SLTDataType* arr;//存储数据 int size;//有效数据个数 int capacity;//空间大小 }SL;//SL是对结构体重命名 //定义顺序表初始化函数声明 void SLInit(SL* ps); 
不直接int,方便以后进行类型的修改,直接在type地方将int修改对结构体重命名—> typedef struct SeqList SL; 也行

SeqList.c

//SeqList.c文件(配合SeqList.h文件) //定义、实现函数 #define _CRT_SECURE_NO_WARNINGS #include"seqlist.h"//包含头文件 void SLInit(SL* ps)//指针接收地址 { ps->arr = NULL; ps->size = 0; ps->capacity = 0; } 

test.c(测试文件)

#define _CRT_SECURE_NO_WARNINGS #include"seqlist.h" void test1() { SL s1; SLInit(&s1);//传地址,传址调用 } int main() { test01(); return 0; }
--这里要注意,使用的是传址调用:将地址传过去,希望对指向的结构体成员进行初始化(修改指向的内容);

--如果是传值调用,只是将结构体成员的内容传过去,形参是实参的临时拷贝(二者是独立的个体),改变了形参的值对实参没有影响。(在test.c文件测试会显示使用了未初始化的变量s1,因为是传值,但代码中s1未初始化,无法传值)
--对于上面三文件的相互配合,通过调试来观察之间的数据传递。调试是很好的习惯,尤其是在模块投入复用前,通过调试验证其正确性,就算调试出有错误也能及时修。保证代码质量、提升开发效率、降低后期维护成本的核心必要环节

四、动态顺序表的应用(初)

--经过上面操作,就得到了一个空顺序表,进行应用。

4.1  在尾部插入数据

SeqList.c文件 //尾插 void SLPushBack(SL* ps, SLTDataType x) { //空间不够 if (ps->size == ps->capacity) { int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity; //增容 SLTDataType* tmp = (SLTDataType*)realloc(ps->arr, newCapacity * sizeof(SLTDataType)); if (tmp == NULL) { perror("realloc fail!"); exit(1); } ps->arr = tmp; ps->capacity = newCapacity; } //空间足够 ps->arr[ps->size++] = x; } //输出_函数 void SLPrint(SL* ps) { for (int i = 0; i < ps->size; i++) { printf("%d ", ps->arr[i]); } printf("\n"); }
test.c文件 //实现尾插 void test02() { SL s2;//创建结构体变量 SLInit(&s2);//初始化 SLPushBack(&s2, 1); SLPrint(&s2); SLPushBack(&s2, 2); SLPrint(&s2); SLPushBack(&s2, 3); SLPrint(&s2); SLPushBack(&s2, 4); SLPrint(&s2); } int main() { test02(); return 0; }


--在程序调试时,运行到函数时,F11进入到函数内部观察变量的变化。
对于增容操作:一般进行成倍数增加(而不是插一个数就申请一个)——>最好2倍增容——>有效降低增容次数,虽存在空间浪费,但不会太多——>默认插入的数据越多,并表示将来存储的数据也越多(概率学)。

 4.2  在头部插入数据

SeqList.c #include "SeqList.h" //扩容_函数 void SLCheckCapacity(SL* ps) { if (ps->size == ps->capacity) { int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity; //增容 SLTDataType* tmp = (SLTDataType*)realloc(ps->arr, newCapacity * sizeof(SLTDataType)); if (tmp == NULL) { perror("realloc fail!"); exit(1); } ps->arr = tmp; ps->capacity = newCapacity; } } //头插_函数 void SLPushFront(SL* ps, SLTDataType 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++;//有效数据+1 }
--后续会频繁进行空间的判断,所以进行函数封装,直接调用函数。

--其次进行了断言操作,防止传参为空。
test.c文件 #include "SeqList.h" void test02() { SL s2;//创建结构体变量 SLInit(&s2);//初始化 //实现头插 SLPushFront(&s2, 1); SLPrint(&s2); SLPushFront(&s2, 2); SLPrint(&s2); SLPushFront(&s2, 3); SLPrint(&s2); } int main() { test02(); return 0; }

结语:顺序表通过连续的物理空间实现了高效的随机访问,但其插入删除的代价也显而易见。但这只是开始——下篇我们将深入更关键的删除、查找等核心操作,并完成最终的性能评估。敬请期待。

Read more

Flutter 组件 tavily_dart 的适配 鸿蒙Harmony 实战 - 驾驭 AI 搜索引擎集成、实现鸿蒙端互联网知识精密获取与语义增强方案

Flutter 组件 tavily_dart 的适配 鸿蒙Harmony 实战 - 驾驭 AI 搜索引擎集成、实现鸿蒙端互联网知识精密获取与语义增强方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 tavily_dart 的适配 鸿蒙Harmony 实战 - 驾驭 AI 搜索引擎集成、实现鸿蒙端互联网知识精密获取与语义增强方案 前言 在鸿蒙(OpenHarmony)生态的智能个人助理、行业垂直类知识中枢以及需要实时获取互联网最新动态并进行 AI 语义加工的各种前沿应用开发中,“信息的有效检索与精准抽取”是决定 AI 应用是否具备“生命感”的关键泵口。面对浩如烟海且充满噪声的互联网网页。如果仅仅依靠传统的关键词匹配。那么不仅会导致应用返回大量无关紧要的垃圾信息。更会因为无法将网页内容转化为 AI 易于理解的结构化上下文(Context),引发严重的 LLM(大语言模型)幻觉风险。 我们需要一种“AI 驱动、语义过滤”的搜索艺术。 tavily_dart 是一套专为 AI

By Ne0inhk
用老 Mac 跑本地 AI:OpenClaw 环境一键搭建

用老 Mac 跑本地 AI:OpenClaw 环境一键搭建

用老 Mac 跑本地 AI:OpenClaw 环境一键搭建 老款 Mac 可以通过一键搭建 OpenClaw 环境,快速部署本地 AI 服务。本文将详细介绍如何使用自动化脚本一键搭建 OpenClaw 环境,让老 Mac 发挥余热,成为强大的本地 AI 工作站。 一、硬件要求 1.1 最低配置 组件最低配置推荐配置说明CPUIntel i3 第 3 代Intel i5 第 4 代及以上支持 VT-x/VT-d内存4GB8GB 或更高DDR3存储128GB SSD256GB SSD 或更高SATA 或 NVMe网络Wi-FiWi-Fi + 有线有线网络优先

By Ne0inhk
【保姆级教程】告别命令行!ClawX:首款 OpenClaw 可视化桌面客户端,零门槛玩转 AI 智能体!

【保姆级教程】告别命令行!ClawX:首款 OpenClaw 可视化桌面客户端,零门槛玩转 AI 智能体!

目录 1、为什么选择 ClawX?(核心亮点) 🎯 零配置门槛 (Zero Configuration) 💬 现代化的聊天体验 ⏰ 可视化的自动化任务 (Cron Automation) 🧩 技能插件市场 (Skill System) 2、技术揭秘:它是如何工作的? 3、快速上手指南 4、注册并获取高性能 API 5、在 ClawX 中接入 API 6、验证连接与初次体验 🚀 结语:这只是冰山一角 在这个“万物皆可 Agent”的时代,我们见证了 OpenClaw 这样优秀的开源项目如何重新定义了 AI 任务编排。它强大、灵活,能帮我们串联起各种复杂的 AI 工作流。 但是,你是否也曾有过这样的困扰? * 想要体验最新的 AI

By Ne0inhk
在家也能做 AI 导演!本地部署 Wan2.1 视频生成模型全攻略

在家也能做 AI 导演!本地部署 Wan2.1 视频生成模型全攻略

文章目录 * 前言 * 1.软件准备 * 1.1 ComfyUI * 1.2 文本编码器 * 1.3 VAE * 1.4 视频生成模型 * 2.整合配置 * 3. 本地运行测试 * 4. 公网使用Wan2.1模型生成视频 * 4.1 创建远程连接公网地址 * 5. 固定远程访问公网地址 * 总结 前言 Wan2.1 模型搭配 ComfyUI 框架,能实现文本转视频、图片转动画等功能,生成的视频质量可媲美专业工具,普通 PC 就能运行,特别适合自媒体创作者、短视频团队和 AI 爱好者快速制作动态内容,无需复杂技术背景也能上手,且完全开源免费,性价比很高。 使用时发现,选择模型版本要结合显卡配置:

By Ne0inhk