嵌入式培训之数据结构学习(三)gdb调试、单向链表练习、顺序表与链表对比
目录
一、gdb调试
(一)一般调试步骤与命令
(二)找段错误(无下断点的地方)
(三)调试命令
二、单向链表练习
1、查找链表的中间结点(用快慢指针)
2、找出链表倒数第k个结点(用快慢指针)
3、链表的逆序
4、链表的插入排序
三、顺序表和链表对比
四、循环链表
一、gdb调试
(一)一般调试步骤与命令
1、gcc -g (调试版本,内含调试信息与源码;eg:gcc -g main.c linklist.c)
2、gdb a.out(调试可执行文件,eg:gdb ./a.out)
3、b fun.c:36 设置断点,运行到这个位置,程序自动暂停
(b :100 默认停在main.c的100行;
b fun.c : 36 停在fun.c的36行
b 函数名 eg: b InserPosLinkList)
4、 r 运行(出现页面要输入则输入)
5、n 执行下一步 步过(如果是函数,直接调用结束)
s 步入自定义函数(系统函数不入)
6、使用p命令,查看变量或指针等数据
(p 变量:显示变量值,eg:p len
p 指针:看地址,eg:p *data)
7、q命令 退出(y)
(二)找段错误(无下断点的地方)
1、gcc -g (加上调试选项-g,eg:gcc main.c linklist.c -g)
2、gdb a.out (调试可执行文件,eg:gdb ./a.out)
3、按 r(run) 直接开始运行
4、重现错误
5、where 找出段错误的位置(出现栈结构信息,从下往上看,找到第一个不是自己写的往后退一个)
eg:#0(第一个不是自己写的,往后退一个)
#1(此处出现段错误)
#2
(三)调试命令
二、单向链表练习
1、查找链表的中间结点(用快慢指针)
(1)算法实现:
LinkNode* FindMidLinkList(LinkList*ll)
// 定义函数,功能是查找链表的中间节点,参数为链表头指针,返回链表节点指针
{
LinkNode* fast = ll->head; // 初始化快指针,指向链表头节点
LinkNode* slow = ll->head; // 初始化慢指针,指向链表头节点
while(fast) // 当快指针不为空时,进行循环
{
fast = fast->next; // 快指针向前移动一个节点
if(NULL == fast) // 检查快指针是否为空(即到达链表末尾)
{
break; // 如果为空,跳出循环
}
slow = slow->next; // 慢指针向前移动一个节点
fast = fast->next; // 快指针再向前移动一个节点
}
return slow; // 循环结束,返回慢指针,此时慢指针指向链表中间节点
}
(2)调试:
2、找出链表倒数第k个结点(用快慢指针)
(1)算法实现:
LinkNode* FindLastKLinkList(LinkList*ll,int k)
// 定义函数,功能是查找链表倒数第k个节点,参数为链表头指针和整数k,返回链表节点指针
{int len = GetSizeLinkList(ll);
if(k < 0 || k > len)
{
return NULL;
}
LinkNode* slow = ll->head; // 初始化慢指针,指向链表头节点
LinkNode* fast = ll->head; // 初始化快指针,指向链表头节点
for(int i = 0 ;i < k ;i++) // 循环k次
{
fast = fast->next; // 快指针向前移动一个节点,共移动k次
}
while(fast) // 当快指针不为空时,进行循环
{
fast =fast->next; // 快指针向前移动一个节点
slow= slow->next; // 慢指针向前移动一个节点
}
return slow; // 循环结束,返回慢指针,此时慢指针指向链表倒数第k个节点
}
(2)调试:
3、链表的逆序
(1)图解
(2)算法实现
int RevertLinkList(LinkList* ll)
{
LinkNode* prev = NULL; // 定义指针prev,用于指向当前节点的前一个节点,初始化为NULL
LinkNode* tmp = ll->head; // 定义指针tmp,指向链表头节点,用于遍历链表
LinkNode* next = tmp->next; // 定义指针next,指向tmp的下一个节点,用于保存tmp后续节点,防止链表断裂
int len = GetSizeLinkList(ll); // 调用GetSizeLinkList函数获取链表长度并存储在len中
if(len<2) // 如果链表长度小于2,即链表为空或只有一个节点
{
return 1; // 无需反转,直接返回1
}
while (1) // 进入无限循环,用于遍历并反转链表
{
tmp->next = prev; // 将当前节点tmp的next指针指向它的前一个节点prev,实现当前节点的反转
prev = tmp; // 将prev指针移动到当前节点tmp的位置,为下一轮循环做准备
tmp = next; // 将tmp指针移动到原本保存的下一个节点next的位置
if (NULL == tmp) break; // 如果tmp指向NULL,说明已经遍历到链表末尾,跳出循环
next = next->next; // 将next指针移动到tmp当前指向节点的下一个节点,为下一轮循环保存后续节点
}
ll->head = prev; // 将链表的头节点更新为反转后链表的头节点(即原链表的尾节点)
return 0; // 成功反转链表,返回0
}
4、链表的插入排序
LinkList* InsertSortLinklist(LinkList* ll)
{
LinkNode* pins = ll->head; // 定义指针pins,指向链表头节点,用于定位插入位置
LinkNode* ptmp = pins->next; // 定义指针ptmp,指向头节点的下一个节点,作为待插入节点
LinkNode* next = ptmp->next; // 定义指针next,指向ptmp的下一个节点,用于保存ptmp后续节点,防止链表断裂
ptmp->next = NULL; // 将待插入节点ptmp的next指针置空,使其暂时脱离原链表
ll->head->next = NULL; // 将原链表头节点的next指针置空,原链表头节点成为新链表的第一个节点,且新链表初始只有这一个节点while(1) // 进入无限循环,用于遍历链表并进行插入排序
{
pins = ll->head; // 每次循环开始,将pins重新指向新链表头节点,从新链表头部开始寻找插入位置
// 当pins后面还有节点,且待插入节点ptmp的年龄值大于pins节点和pins下一个节点的年龄值时
while(pins->next && ptmp->data.age > pins->data.age && ptmp->data.age > pins->next->data.age)
{
pins = pins->next; // 移动pins指针,向后寻找合适的插入位置
}if(pins->data.age > ptmp->data.age) // 如果找到的位置pins节点的年龄值大于待插入节点ptmp的年龄值
{
ptmp->next = ll->head; // 将待插入节点ptmp的next指针指向新链表头节点
ll->head = ptmp; // 更新新链表头节点为ptmp,即将ptmp插入到新链表头部
}
else // 否则(即pins节点的年龄值小于等于ptmp的年龄值)
{
ptmp->next = pins->next; // 将待插入节点ptmp的next指针指向pins的下一个节点
pins->next = ptmp; // 将pins的next指针指向ptmp,即将ptmp插入到pins之后
}
ptmp = next; // 将ptmp指针移动到原本保存的下一个节点next的位置,准备处理下一个待插入节点
if(NULL == ptmp) // 如果ptmp指向NULL,说明已经处理完所有节点
{
break; // 跳出循环
}
next = next->next; // 将next指针移动到ptmp当前指向节点的下一个节点,为下一轮循环保存后续节点
ptmp->next = NULL; // 将待插入节点ptmp的next指针置空,使其暂时脱离原链表
}
return ll; // 返回排序后的链表头指针
}
三、顺序表和链表对比
1、存储方式
顺序表 是一段连续的存储单元
链表 是逻辑结构连续物理结构(在内存中的表现形式)不连续(因为是通过malloc获得的)
2、 时间性能
查找 : 顺序表O(1) //按规则放,找的时候按规则找;支持随机访问
链表 O(n) //只能从第一个往后找
插入和删除:顺序表 O(n) //整体前移与后移
链表 O(1) //一次性改(只需把一个节点连上),与链表数据量无关
3、 空间性能
顺序表 需要预先分配空间,大小固定;只放数据
链表, 不需要预先分配,大小可变,动态分配;数据 + 指针域
四、循环链表
1、 简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或
头结点,链表就成了一个环,头尾相连,就成了循环链表。circultlar linker list.
2、 注意非空表,和空表。多数会加入头结点。
3、 原来结束的条件是 p->next != NULL ------->>>>> p-next != Head
4、练习:判断链表是否有环(用快慢指针)
int IsRingLinkList(LinkList* ll)
// 定义函数判断链表是否有环,参数为链表指针,返回整型(0表示无环,1表示有环)
{
LinkNode* fast = ll->head; // 定义快指针fast,初始指向链表头节点
LinkNode* slow = ll->head; // 定义慢指针slow,初始也指向链表头节点
while (fast) // 当快指针不为空时进入循环(快指针为空时说明已遍历到链表末尾,无环)
{
fast = fast->next; // 快指针先移动一步(每次移动两步的第一步)
if (NULL == fast) // 检查快指针移动后是否为空
{
return 0; // 若为空,说明链表无环,返回0
}
if (slow == fast) // 检查慢指针和快指针是否相遇(相遇则说明有环)
{
return 1; // 若相遇,返回1表示有环
}
fast = fast->next; // 快指针再移动一步(完成每次移动两步)
slow = slow->next; // 慢指针每次移动一步
}
return 0; // 循环结束后仍未相遇,说明链表无环,返回0
}
相关文章:

嵌入式培训之数据结构学习(三)gdb调试、单向链表练习、顺序表与链表对比
目录 一、gdb调试 (一)一般调试步骤与命令 (二)找段错误(无下断点的地方) (三)调试命令 二、单向链表练习 1、查找链表的中间结点(用快慢指针) 2、找出…...

虚拟机安装CentOS7网络问题
虚拟机安装CentOS7网络问题 1. 存在的问题1.1 CentOS7详细信息 2. 解决问题3.Windows下配置桥接模式 1. 存在的问题 虽然已经成功在虚拟机上安装了CentOS7,但是依旧不能上网。 1.1 CentOS7详细信息 [fanzhencentos01 ~]$ hostnamectlStatic hostname: centos01Ic…...
零基础学Java——终章:核心知识点与面试总结
Java核心知识点与面试总结 本文档旨在总结Java的核心知识点,并提供常见的面试问题与解答,帮助学习者巩固知识和准备面试。 目录 零基础学Java——大纲合集 Java基础 1. Java概述 JDK (Java Development Kit): Java开发工具包,包含Java的…...

迅为RK3588开发板安卓GPIO调用APP运行测试
将网盘上的安卓工程文件复制到 Windows 电脑上。确保工程路径中使用英文字符,不包含中文。接着,启动 Android Studio,点击“Open”按钮选择应用工程文件夹,然后点击“OK”。由于下载 Gradle 和各种 Jar 包可能需要一段时间&#x…...
在一台CentOS服务器上开启多个MySQL服务
1. 创建目录 mkdir -p /data/mysql3307/{data,tmp,logs} # 赋权 chown -R mysql:mysql /data/mysql3307 chmod -R 750 /data/mysql3307 2.修改 /etc/my.cnf ,添加[mysqld3307]实例配置组 [mysqld3307] # mysql服务的端口 port 3307 # 套接字文件存放路径 socket /…...
C#高级编程:IO和序列化
在 C# 编程中,输入输出(IO)和序列化是两个至关重要的概念,它们为数据的存储、读取以及在不同环境间的传输提供了强大的支持。无论是开发小型应用程序,还是构建复杂的企业级系统,深入理解并熟练运用 IO 和序列化技术都是必不可少的。 一、C# 中的 IO 基础 1、文件流…...

Unity 红点系统
首先明确一个,即红点系统的数据结构是一颗树,并且红点的数据结构的初始化需要放在游戏的初始化中,之后再是对应的红点UI侧的注册,对应的红点UI在销毁时需要注销对红点UI的显示回调注册,但是不销毁数据侧的红点注册 - …...

尼康VR镜头防抖模式NORMAL和ACTIVE的区别(私人笔记)
1. NORMAL 模式(常规模式) 适用场景:一般手持拍摄,比如人像、静物、风景或缓慢平移镜头(如水平追拍)等。工作特性: 补偿手抖引起的小幅度震动(比如手持时自然的不稳)&am…...
JMeter 中通过 WebSocket (WS) 协议发送和接收 Protocol Buffers (Proto) 消息
在 JMeter 中通过 WebSocket (WS) 协议发送和接收 Protocol Buffers (Proto) 消息,需要使用 JMeter WebSocket 插件,并结合 JSR223 脚本处理 Proto 的序列化和反序列化。以下是完整步骤: 1. 准备工作 1.1 安装 WebSocket 插件 下载插件&…...

从索引中排除 Elasticsearch 字段
作者:来自 Elastic Kofi Bartlett 说明如何配置 Elasticsearch 排除字段、为什么要这样做,以及应遵循的最佳实践。 更多阅读:Elasticsearch:inverted index,doc_values 及 source 想获得 Elastic 认证?了解…...
【Android】文件分块上传尝试
【Android】文件分块上传 在完成一个项目时,遇到了需要上传长视频的场景,尽管可以手动限制视频清晰度和视频的码率帧率,但仍然避免不了视频大小过大的问题,且由于服务器原因,网络不太稳定。这个时候想到了可以将文件分…...

超详细Docker教程
前言:大家在在Linux上部署mysql及其他软件时,大家想一想自己最大的感受是什么? 我相信,除了个别天赋异禀的人以外,大多数人都会有相同的感受,那就是麻烦。核心体现在三点: 命令太多了ÿ…...

Java项目拷打(外卖+点评)
一、点评星球(黑马点评) 1、项目概述 1.1、项目简介 本项目是基于Spring Boot与Redis深度整合的前后端分离的点评平台。系统以Redis为核心技术支撑,重点解决高并发场景下的缓存穿透、击穿、雪崩等问题,涵盖商户展示、优惠券秒杀…...
hadoop中了解yarm
Hadoop中的YARN(Yet Another Resource Negotiator)是一种新的Hadoop资源管理器,是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度。以下是其相关介绍: 核心思想 将JobTracker的资源管理和作业调度/监控功…...
Android usb网络共享详解
Android usb网络共享详解 文章目录 Android usb网络共享详解一、前言二、USB网络共享使用的前提1、Android设备支持adb 并且打开usb开关2、原生Settings能看到USB网络共享开关3、代码中检测USB网络共享是否支持 三、Settings 中USB网络共享代码的部分代码1、Settings\res\xml\t…...
【数据库知识】Mysql进阶-高可用MHA(Master High Availability)方案
mysql高可用MHA(Master High Availability)方案 集群部署模式下的高可用方案一、高可用架构原理1. 核心组件2. 故障切换流程 二、详细部署步骤 (3节点集群)1. 环境准备2. 节点配置(以 node1 为例)3. 初始化集群4. 部署MySQL Route…...
Web 架构之会话保持深度解析
文章目录 一、引言二、会话保持的基本概念2.1 什么是会话2.2 为什么需要会话保持 三、会话保持的常见实现方式3.1 基于客户端的会话保持3.1.1 Cookie 方式3.1.2 URL 重写方式 3.2 基于服务器端的会话保持3.2.1 负载均衡器会话保持3.2.2 会话共享 四、会话保持可能遇到的问题及解…...

微信小程序仿淘宝拍照/照片点位识图、点位裁剪生图、图片裁剪组件、图片点位框选、裁剪生成图片,canvasToImg
实现效果 效果: 1.微信小程序仿淘宝拍照/照片点位识图、根据点位裁剪生图、图片可裁剪、图片高度可控 2.识别点位自动生成标准构图方案,支持手动微调实现像素级精准裁剪 3.可以根据接口识别的点位信息实现拍照/相册图片特征点自动识别并裁剪 实现步骤 …...
attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作获取第二维度,第三维度
attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作获取第1 维度,第二维度 attention_weights = torch.ones_like(prompt_embedding[:, :, 0]) 这行代码的作用是创建一个与 prompt_embedding[:, :, 0] 形状相同且所有元素都为 1 的张量,它用于初始化…...
Rust入门之高级Trait
Rust入门之高级Trait - 本文源码 引言 前面学习了迭代器(Iterators),Iterator源码中就用到了关联类型的功能。关联类型就属于高级trait的内容,这次我们学习一下高级trait,了解关联类型等知识。关联类型看似和泛型相…...
从 Set、Map 到 WeakSet、WeakMap 的进阶之旅
在 ES5 时代,JavaScript 的数据结构主要依赖于两种类型:数组和对象。然而,随着应用规模的增长和复杂性上升,传统的数据结构越来越难以满足开发需求。比如,需要一个能自动去重的集合、一个支持任意类型键名的字典、一个…...
TTL (Time-To-Live) 解析
文章目录 TTL (Time-To-Live) 解析:网络与Java中的应用一、TTL的定义二、TTL在网络中的应用1. **路由和数据包的生命周期**2. **DNS中的TTL**3. **防止环路** 三、TTL在Java中的应用1. **缓存管理**2. **Java中的ThreadLocal**3. **网络通信中的TTL** 四、TTL的注意…...

Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载
一、前言 搞定了实时预览后,另一个功能就是录像回放,录像回放和视频点播功能完全一致,唯一的区别就是发送点播的sdp信息中携带了开始时间和结束时间,因为是录像文件,所以有这个时间,而实时视频预览这个对应…...

季报中的FPGA行业:U型反转,春江水暖
上周Lattice,AMD两大厂商相继发布2025 Q1季报,尽管恢复速度各异,但同时传递出FPGA行业整体回暖的复苏信号。 5月5日,Lattice交出了“勉强及格”的答卷,报告季度营收1亿2000万,与华尔街的预期基本相符。 对于这家聚焦在中小规模器件的领先厂商而言,按照其CEO的预期,长…...

嵌入式机器学习平台Edge Impulse图像分类 – 快速入门
陈拓 2025/05/08-2025/05/11 1. 简介 官方网址 https://edgeimpulse.com/ 适用于任何边缘设备的人工智能: Gateways - 网关 Sensors & Cameras - 传感器和摄像头 Docker Containers - Docker容器 MCUs, NPUs, CPUs, GPUs 构建数据集、训练模型并优化库以…...
web 自动化之 yaml 数据/日志/截图
文章目录 一、yaml 数据获取二、日志获取三、截图 一、yaml 数据获取 需要安装 PyYAML 库 import yaml import os from TestPOM.common import dir_config as Dir import jsonpathclass Data:def __init__(self,keyNone,file_name"test_datas.yaml"):file_path os…...
ARMV8 RK3399 u-boot TPL启动流程分析 --start.S
上电后运行的第一支文件:arch/arm/cpu/armv8/start.S CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK1 #include <asm/arch/boot0.h> 跳转到 arch/arm/include/asm/arch-rockchip/boot0.h CONFIG_SPL_BUILD1 b 1f ROCKCHIP_EARLYRETURN_TO_BROMno TINY_FRAMEWORKno …...

zst-2001 上午题-历年真题 计算机网络(16个内容)
网络设备 计算机网络 - 第1题 ac 计算机网络 - 第2题 d 计算机网络 - 第3题 集线器不能隔离广播域和冲突域,所以集线器就1个广播域和冲突域 交换机就是那么的炫,可以隔离冲突域,有4给冲突域,但不能隔离广播域…...

使用termius连接腾讯云服务器
使用termius连接腾讯云服务器 1.下载termius termius官网 安装配置教程 这里安装的window版本> 默认安装到C盘,不建议修改路径 可以选择谷歌登录,也可以不登录,软件是免费的,试用的是付费版本,不需要点 2.配置 这里…...
redis 命令大全整理
http://doc.redisfans.com/ 原网址 Redis 命令分类 Key(键) Key(键)命令 exists/del/keys/type/scanobject/move/dump/migratettl/pttl/persist/expireat/pexpireat/expire/pexpirerename/renamenxsort/randomkey/restoreexists 语法:exists key [key ...] 检查一个或多…...