当前位置: 首页 > article >正文

考研复习 Day13| 数据结构与算法--线性表

一、线性表的定义和基本操作1.1 线性表的定义线性表由n(n≥0)个相同数据类型的元素组成的有限序列。表示形式L (a₁, a₂, ···, aᵢ, aᵢ₊₁, ···, aₙ)术语说明n表长n0 时为空表a₁表头元素唯一的“第一个”元素aₙ表尾元素唯一的“最后一个”元素直接前驱除第一个元素外每个元素有且仅有一个直接后继除最后一个元素外每个元素有且仅有一个线性表的特点特点说明元素个数有限—逻辑上的顺序性元素之间存在明确的先后次序元素不可分割每个元素是独立单位数据类型相同每个元素占有相同大小的存储空间抽象性只讨论逻辑关系不考虑具体内容注线性表是逻辑结构顺序表和链表是存储结构二者属于不同层面的概念不要混淆。1.2 线性表的基本操作操作描述InitList(L)初始化表构造空线性表Length(L)求表长返回元素个数LocateElem(L, e)按值查找返回元素位置GetElem(L, i)按位查找获取第i个元素值ListInsert(L, i, e)插入操作在第i个位置插入eListDelete(L, i, e)删除操作删除第i个元素并用e返回PrintList(L)输出操作按顺序输出所有元素Empty(L)判空操作DestroyList(L)销毁操作释放内存空间注① 基本操作的具体实现取决于存储结构② 符号表示C引用调用C语言中可通过指针实现第二部分顺序表线性表的顺序存储2.1 顺序表的定义顺序表用一组地址连续的存储单元依次存储线性表中的数据元素逻辑上相邻的元素在物理位置上也相邻。存储地址计算设顺序表L的起始地址为LOC(A)每个元素占sizeof(ElemType)字节则第i个元素的存储地址为LOC(aᵢ) LOC(A) (i-1) × sizeof(ElemType)随机存取可在 O(1) 时间内直接访问任意位置的元素。存储结构描述1静态分配#define MaxSize 50 typedef struct { ElemType data[MaxSize]; int length; } SqList;静态分配时数组大小在编译时固定空间占满后无法插入新元素。2动态分配#define InitSize 100 typedef struct { ElemType *data; int MaxSize, length; } SeqList;C语言动态分配L.data (ElemType*)malloc(sizeof(ElemType) * InitSize);C动态分配L.data new ElemType[InitSize];注意动态分配仍然是顺序存储结构支持随机存取只是存储空间可动态调整。顺序表的优缺点优点缺点① 随机访问O(1)时间① 插入删除需移动大量元素O(n)② 存储密度高无额外指针开销② 需要连续存储空间不够灵活2.2 顺序表上基本操作的实现考点追踪顺序表上操作的时间复杂度分析20231. 顺序表的初始化静态分配void InitList(SqList L) { L.length 0; }动态分配void InitList(SeqList L) { L.data (ElemType*)malloc(InitSize * sizeof(ElemType)); L.length 0; L.MaxSize InitSize; }2. 插入操作可以就像一个排好队的一排人要往其中某个位置插入一人新元素因此在插入位置后面的人要从尾部开始依次退后不然就会踩脚导致插入数据出现错误在第i个位置1≤i≤L.length1插入新元素e。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 j L.length; j i; j--) L.data[j] L.data[j - 1]; L.data[i - 1] e; L.length; return true; }时间复杂度分析情况移动次数时间复杂度最好表尾插入in10O(1)最坏表头插入i1nO(n)平均n/2O(n)注意位序从1开始数组下标从0开始注意转换。3. 删除操作删除第i个位置1≤i≤L.length的元素用e返回其值。bool ListDelete(SqList L, int i, ElemType e) { if (i 1 || i L.length) return false; e L.data[i - 1]; for (int j i; j L.length; j) L.data[j - 1] L.data[j]; L.length--; return true; }时间复杂度分析情况移动次数时间复杂度最好删除表尾in0O(1)最坏删除表头i1n-1O(n)平均(n-1)/2O(n)4. 按值查找顺序查找int LocateElem(SqList L, ElemType e) { for (int i 0; i L.length; i) if (L.data[i] e) return i 1; return 0; }时间复杂度平均比较次数 (n1)/2 →O(n)第三部分线性表的链式表示3.1 单链表的定义考点追踪单链表的应用2009、2012、2013、2015、2016、2019结点结构结点类型定义typedef struct LNode { ElemType data; struct LNode *next; } LNode, *LinkList;头指针与头结点类型空表判断带头结点L-next NULL不带头结点L NULL引入头结点的优点方便操作操作统一性首部插入/删除与其他位置逻辑一致空表与非空表处理统一头指针始终非空3.2 单链表上基本操作的实现注默认链表带头结点1. 单链表的初始化bool InitList(LinkList L) { L (LNode*)malloc(sizeof(LNode)); L-next NULL; return true; }2. 求表长int Length(LinkList L) { int len 0; LNode *p L-next; while (p ! NULL) { len; p p-next; } return len; }时间复杂度O(n)3. 按序号查找LNode *GetElem(LinkList L, int i) { LNode *p L; int j 0; while (p ! NULL j i) { p p-next; j; } return p; }4. 按值查找LNode *LocateElem(LinkList L, ElemType e) { LNode *p L-next; while (p ! NULL p-data ! e) p p-next; return p; }时间复杂度O(n)5. 插入结点操作考点追踪单链表插入操作的过程2016、2024bool ListInsert(LinkList L, int i, ElemType e) { LNode *p L; int j 0; while (p ! NULL j i - 1) { p p-next; j; } if (p NULL) return false; LNode *s (LNode*)malloc(sizeof(LNode)); s-data e; s-next p-next; // 1 新结点指向原后继 p-next s; // 2 前驱指向新结点 return true; }重要步骤①和②的顺序不可颠倒否则会丢失后继地址。时间复杂度O(n)主要开销在查找前驱。若已知结点指针后插操作O(1)。前插操作的技巧O(1)时间将新结点*s插入目标结点*p之后再交换*p与*s的数据域逻辑上等效于前插s-next p-next; p-next s; // 交换数据域 ElemType temp p-data; p-data s-data; s-data temp;6. 删除结点操作bool ListDelete(LinkList L, int i, ElemType e) { LNode *p L; int j 0; while (p-next ! NULL j i - 1) { p p-next; j; } if (p-next NULL) return false; LNode *q p-next; e q-data; p-next q-next; free(q); return true; }时间复杂度O(n)删除给定结点*p的技巧O(1)时间不能用于尾结点将*p后继结点的数据值复制到*p中然后删除其后继结点。LNode *q p-next; p-data p-next-data; p-next q-next; free(q);7. 头插法建立单链表LinkList List_HeadInsert(LinkList L) { LNode *s; int x; L (LNode*)malloc(sizeof(LNode)); L-next NULL; scanf(%d, x); while (x ! 9999) { s (LNode*)malloc(sizeof(LNode)); s-data x; s-next L-next; L-next s; scanf(%d, x); } return L; }每插入一个结点O(1)总时间复杂度O(n)。元素顺序与输入顺序相反。8. 尾插法建立单链表LinkList List_TailInsert(LinkList L) { int x; L (LNode*)malloc(sizeof(LNode)); LNode *s, *r L; scanf(%d, x); while (x ! 9999) { s (LNode*)malloc(sizeof(LNode)); s-data x; r-next s; r s; scanf(%d, x); } r-next NULL; return L; }附设尾指针时间复杂度O(n)。元素顺序与输入顺序一致。类比CSTL库中的vector的push_back尾插操作。3.3 双链表结点类型定义typedef struct DNode { ElemType data; struct DNode *prior, *next; } DNode, *DLinkList;插入操作在结点p之后插入s考点追踪双链表中插入操作的实现2023s-next p-next; // 1 p-next-prior s; // 2 s-prior p; // 3 p-next s; // 4步骤①必须在步骤④之前否则会丢失后继地址。这让我想到了一句话干事之前要先安排好后路即先要指向后继结点防止丢失后继地址也就是步骤1删除操作删除结点p的后继q考点追踪双链表中删除操作的实现2016p-next q-next; q-next-prior p; free(q);3.4 循环链表循环单链表尾结点的next指向头结点判空条件L-next L从任意结点出发可遍历整个链表考点追踪循环单链表中删除首元素的操作2021循环双链表头结点的prior指向尾结点尾结点的next指向头结点3.5 静态链表用数组模拟链式存储指针用数组下标游标表示。#define MaxSize 50 typedef struct { ElemType data; int next; // 下一个元素的数组下标 } SLinkList[MaxSize];结束标志next -13.6 顺序表和链表的比较比较维度顺序表链表存取方式随机存取 O(1)顺序存取 O(n)逻辑与物理结构逻辑相邻⇔物理相邻逻辑相邻≠物理相邻按值查找无序O(n)有序O(log₂n)O(n)按序号查找O(1)O(n)插入/删除需移动约一半元素 O(n)修改指针 O(1)已知位置空间分配需预分配容量按需扩展但每结点有指针开销存储密度高1低1选择建议场景推荐结构规模稳定、以随机访问为主顺序表动态性强、频繁插入删除链表思考1. 顺序表 ≈ 数组连续内存、随机访问、插入删除慢——就是它的全部特点。2. 链表每个结点“拿着”下一个结点的地址。就像寻宝游戏每张纸条写着下一个线索的位置。尾插法莫名得让我想到了“人体蜈蚣”《十宗罪》看多了3. 头结点的意义 ≈ 哨兵在链表头部加一个不存数据的“哨兵”让空链表和非空链表的操作统一减少边界判断。这和编程中在数组前后加“哨兵”简化循环的逻辑是一样的。4. 类比学习学习这些数据结构时让我很容易地就想到了CSTL库中已封装好的listvector等其他容器其实本质是同一套只不过C中的更方便使用。注以上内容参考 2027年数据结构考研复习指导 王道论坛 组编其中有一些个人想法如有任何错误或不妥欢迎各位大佬指出如果各位有一些有意思的想法也可以和我交流一下~感谢明日计划栈和队列与数组

相关文章:

考研复习 Day13| 数据结构与算法--线性表

一、线性表的定义和基本操作1.1 线性表的定义线性表:由 n(n≥0) 个相同数据类型的元素组成的有限序列。表示形式:L (a₁, a₂, , aᵢ, aᵢ₊₁, , aₙ)术语说明n表长;n0 时为空表a₁表头元素(唯一的“第一个”元素)aₙ…...

从播放到管理:用Vue3 + Pinia打造一个‘不打架’的多音频播放页(附完整代码)

构建互斥音频播放系统:Vue3与Pinia的实战解决方案 在语言学习平台、有声书应用或产品演示页面中,多音频交互是常见需求。当用户点击播放A音频时,B音频需要自动暂停——这种看似简单的逻辑背后,隐藏着状态同步、事件通信和性能优化…...

从零开始:在Android Studio中高效配置与调试AOSP源码

1. 为什么要在Android Studio中配置AOSP源码 第一次接触AOSP源码的开发者可能会有疑问:为什么非要把这么庞大的代码导入IDE?用文本编辑器查看不行吗?这个问题我也曾经思考过,直到真正尝试在Android Studio中调试过源码后&#xff…...

Gitee:AI赋能的国产研发协作平台如何重塑企业数字化进程

在数字化转型成为企业核心战略的当下,项目管理软件已经从简单的任务追踪工具进化为驱动研发效能提升的智能中枢。作为国内领先的代码托管与研发协作平台,Gitee(码云)凭借其全栈式解决方案与AI深度融合能力,正重新定义项…...

从焊接角度谈芯片封装:SOP/SOIC/MSOP的工艺要点与常见问题解决

从焊接角度谈芯片封装:SOP/SOIC/MSOP的工艺要点与常见问题解决 在电子制造领域,芯片封装的选择与焊接工艺直接影响着产品的可靠性和性能表现。SOP、SOIC和MSOP作为表面贴装技术(SMT)中最常见的封装类型,其焊接质量往往决定了电路板的良品率。…...

提升树(Boosting Tree)实战:从原理到Python实现

1. 提升树算法入门:从决策树到集成学习 提升树(Boosting Tree)是机器学习中一种强大的集成学习方法,它通过组合多个弱学习器(通常是决策树)来构建一个强学习器。我第一次接触这个概念是在解决一个房价预测问题时,当时单…...

从“惯性思维”到“规则驱动”:一次微信小程序修复引发的 AI 编程范式思考

最近,我在 Qoder(我们的 AI 编程助手)身上经历了一次深刻的“复盘”。这源于一个看似简单的微信小程序开发任务——自定义导航栏在刘海屏上的适配,(我之前项目,qoder能很好的完成任务,但这次却是…...

不止是交换机监控:手把手教你用CactiEZ同时管好Windows和Linux服务器

异构IT环境监控实战:用CactiEZ统一管理Windows与Linux服务器 混合IT环境下的监控一直是运维人员的痛点。当你的网络里同时存在Cisco交换机、Windows Server和Ubuntu Linux服务器时,能否用一个工具实现统一监控?CactiEZ给出了肯定答案。这个基…...

告别网络卡顿!用国内镜像源+一键脚本5分钟搞定ROS2(Foxy/Humble/Jazzy)

5分钟极速部署ROS2:国内镜像源与智能脚本实战指南 为什么你的ROS2安装总是失败? 每次看到终端里卡在99%的进度条或是红色的GPG错误提示,是不是恨不得砸键盘?作为国内开发者,我们早已习惯了与境外服务器斗智斗勇的日常。…...

Java 面试手撕排序封神版!八大排序算法(快排 / 堆排 / 归并)手敲无 bug,面试直接默写

面试手撕排序整理完整版 面试中常考的手撕排序算法整理&#xff0c;可以直接照抄&#xff0c;包含 快速排序归并排序堆排序希尔排序直接插入排序选择排序计数排序冒泡排序 快速排序 丐版实现 public static void quickSort(ArrayList<Integer> arr, int begin, int end){…...

手把手教你用STM32CubeMX配置FOC必备的互补PWM:从中心对齐模式到ADC采样点全解析

STM32CubeMX实战&#xff1a;FOC控制中互补PWM与ADC采样的黄金配置法则 在电机控制领域&#xff0c;磁场定向控制&#xff08;FOC&#xff09;因其卓越的性能表现已成为工业驱动和高精度伺服系统的首选方案。而实现FOC算法的关键硬件基础&#xff0c;便是能够精准输出互补PWM波…...

零基础搞定!全平台 Python + VS Code 开发环境配置保姆级教程

对于刚接触编程的新手来说&#xff0c;编写第一行代码前的“环境配置”往往是最劝退的环节。环境变量是什么&#xff1f;为什么我的终端提示找不到命令&#xff1f;别担心&#xff0c;这篇文章将手把手带你在 Windows、macOS 和 Linux 上搭建目前最流行、最轻量级的开发组合&am…...

深色模式(Dark Mode)适配指南

深色模式适配指南&#xff1a;打造舒适夜间体验 随着移动设备和操作系统的广泛支持&#xff0c;深色模式&#xff08;Dark Mode&#xff09;已成为现代用户界面的重要设计趋势。它不仅能够减少屏幕对眼睛的刺激&#xff0c;还能在低光环境下提升可读性&#xff0c;同时节省设备…...

Audit Log(审计日志)介绍(对系统中关键操作行为记录,用户行为+系统变更+安全事件)中间件 / AOP、数据库层——数据库变更捕获(CDC)

文章目录AuditLog&#xff08;审计日志&#xff09;详解&#xff1a;从概念到实践一、什么是 Audit Log&#xff1f;二、为什么需要审计日志&#xff1f;1. 安全审计与合规要求2. 问题追踪与责任界定3. 内部风险控制三、审计日志 vs 普通日志四、审计日志记录什么&#xff1f;1…...

新加坡ACRA BizFile介绍(新加坡会计与企业监管局Accounting and Corporate Regulatory Authority提供的在线服务平台)

文章目录新加坡ACRA BizFile新加坡ACRA BizFile ACRA BizFile 是新加坡会计与企业监管局&#xff08;Accounting and Corporate Regulatory Authority&#xff0c;简称 ACRA&#xff09;提供的一个在线服务平台。通过 BizFile&#xff0c;用户可以查询和获取新加坡注册公司的公…...

Simulink MinMax模块避坑指南:当uint8遇上int8,仿真结果为何会‘丢1’?

Simulink MinMax模块数据类型陷阱&#xff1a;uint8与int8混合运算的“幽灵减1”现象解析 在嵌入式系统建模领域&#xff0c;Simulink作为行业标准工具链的核心组件&#xff0c;其模块库的稳定性直接关系到数百万工程师的日常开发效率。然而&#xff0c;即使是经过严格验证的基…...

从HTTP协议到XSS攻击:为什么你的Web服务器必须禁用TRACE方法?

从HTTP协议到XSS攻击&#xff1a;为什么你的Web服务器必须禁用TRACE方法&#xff1f; 在Web开发的世界里&#xff0c;安全性往往隐藏在那些看似无害的协议细节中。TRACE方法就像HTTP协议家族中那个被遗忘的成员——它本意善良&#xff0c;却在不经意间成为了攻击者的帮凶。想象…...

如何高效使用LRCGET:离线歌词同步完整指南

如何高效使用LRCGET&#xff1a;离线歌词同步完整指南 【免费下载链接】lrcget Utility for mass-downloading LRC synced lyrics for your offline music library. 项目地址: https://gitcode.com/gh_mirrors/lr/lrcget 你是否曾面对数千首离线音乐&#xff0c;却因缺少…...

金三银四,一个面试官连连夸赞的个人网页技术分享

智能体时代的代码范式转移与 C# 的战略转型 传统的 C# 开发模式&#xff0c;即所谓的“工程导向型”开发&#xff0c;要求开发者创建一个复杂的项目结构&#xff0c;包括项目文件&#xff08;.csproj&#xff09;、解决方案文件&#xff08;.sln&#xff09;、属性设置以及依赖…...

系统故障排查思路

系统故障排查思路&#xff1a;从混乱到有序的解决之道 在数字化时代&#xff0c;系统故障是每个技术团队都可能面临的挑战。无论是服务器宕机、应用程序崩溃&#xff0c;还是网络延迟&#xff0c;这些问题都可能对业务造成严重影响。如何高效、准确地定位并解决故障&#xff0…...

别再傻傻点图标了!用CMD命令玩转Windows远程桌面,效率翻倍(附常用参数清单)

告别图形界面&#xff1a;用命令行玩转Windows远程桌面的高阶技巧 每次连接远程服务器都要重复点击图标、输入地址、调整分辨率&#xff1f;对于需要频繁管理多台设备的运维人员和开发者来说&#xff0c;这种低效操作简直是在浪费生命。今天我要分享的是如何通过CMD命令和批处理…...

基于Halcon视觉技术的PCB元件缺失检测实战指南

1. 为什么选择Halcon进行PCB元件缺失检测 在电子制造业中&#xff0c;PCB&#xff08;印刷电路板&#xff09;的质量控制至关重要。一个缺失的电阻、电容或其他元件可能导致整个电路板无法正常工作。传统的人工目检方式效率低下且容易出错&#xff0c;而Halcon作为工业视觉领域…...

Java8 Stream sorted排序实战:从Comparator基础到多级排序进阶

1. 从零开始理解Stream sorted排序 第一次接触Java8的Stream sorted方法时&#xff0c;我盯着那段链式调用的代码看了足足十分钟。就像刚拿到新手机的老人&#xff0c;明明按键就在眼前&#xff0c;却不知道从哪下手。后来在实际项目中踩过几次坑才明白&#xff0c;sorted()本质…...

DataX 实战:从零构建跨库数据同步解决方案

1. 为什么选择DataX进行跨库数据同步 第一次接触DataX是在处理一个电商平台的订单数据迁移项目。当时需要将MySQL中的3000万条订单数据同步到阿里云的AnalyticDB进行分析&#xff0c;尝试了多种方案后&#xff0c;DataX的表现让我印象深刻。相比传统的SQL导出导入方式&#xff…...

Excel炒股党必备:手把手教你用Power Query免费获取并刷新股票历史数据

Excel炒股党必备&#xff1a;手把手教你用Power Query免费获取并刷新股票历史数据 在投资分析领域&#xff0c;数据更新速度往往决定着决策质量。对于习惯使用Excel的投资者来说&#xff0c;每次手动复制粘贴股票数据不仅效率低下&#xff0c;还容易出错。其实Excel内置的Power…...

管理SELinux安全性知识点问答

1.SELinux是如何保护资源的? SELinux给进程和文件指定了规则&#xff0c;严格按照规则限制文件和进程&#xff0c;默认拒绝所有未明确的操作来保护资源。 2.什么是强制访问控制(MAC)?它有什么特点? 强制访问控制是由系统统一强制决定进程/用户对文件/设备的访问权限。用户和…...

kotlin中一般用高介函数代替return

在 Kotlin 里完全可以不用 break &#xff0c;而且日常开发基本都这么写。 我给你按场景列全&#xff0c;都是实际开发里最常用的替代方案&#xff0c;一看就会。集合高阶函数&#xff08;最常用&#xff0c;直接替代 break&#xff09; 找到第一个满足条件就停&#xff08;等…...

AI编程革命:Codex如何重塑脚本开发效率

技术文章大纲&#xff1a;告别重复造轮子——利用Codex高效编写脚本核心价值与痛点分析重复性脚本开发的低效现状 人工编写脚本的常见问题&#xff1a;语法错误、逻辑冗余、调试耗时 Codex如何通过自然语言理解降低脚本开发门槛Codex基础能力解析自然语言到代码的转换机制 支持…...

Kelsey Hightower在KubeCon 2026:面对AI,人人都是初级工程师

Electrolux站点可靠性产品经理Kristina Kondrashevich清晰地记得Kelsey Hightower对她工作产生的深刻影响。"我们参加了KubeCon 2023&#xff0c;Kelsey Hightower在那次大会上做了一场关于开源项目的演讲&#xff0c;"Kondrashevich告诉The New Stack&#xff0c;&q…...

告别数据焦虑:用MedAugment给你的医学影像数据集‘打鸡血’(附Python实战代码)

告别数据焦虑&#xff1a;用MedAugment给你的医学影像数据集‘打鸡血’&#xff08;附Python实战代码&#xff09; 当你面对只有几十张标注好的医学影像数据时&#xff0c;是否感到无从下手&#xff1f;作为经历过这种困境的开发者&#xff0c;我清楚地记得第一次尝试用200张皮…...