【数据结构与算法】单链表的综合运用:1.合并两个有序链表 2.分割链表 3.环形链表的约瑟夫问题

【数据结构与算法】单链表的综合运用:1.合并两个有序链表 2.分割链表 3.环形链表的约瑟夫问题
在这里插入图片描述
🔥小龙报:个人主页
🎬作者简介:C++研发,嵌入式,机器人等方向学习者
❄️个人专栏:《C语言》《【初阶】数据结构与算法》
永远相信美好的事情即将发生
在这里插入图片描述

文章目录


前言

链表是C语言数据结构的核心内容,也是算法面试的高频考点,其灵活的指针操作与逻辑构建对编程思维要求颇高。本文聚焦链表经典实操题型,从合并有序链表、分割链表到环形链表约瑟夫问题,由浅入深拆解解题思路,结合哨兵位、循环计数等实用技巧,通过清晰的算法原理与完整代码实现,帮读者吃透链表操作逻辑,夯实数据结构基础。

一、合并两个有序链表

1.1题目

链接:合并两个有序链表

在这里插入图片描述

1.2 算法原理

核心:判断大小 + 链表为插 + 建立一个哨兵位
和合并两个有序数组的思路一样,定义四个指针
newhead和newtail:新链表的头尾节点
pcur1和pcur2:分别指向两个要合并的链表的头节点
技巧:可以malloc一块空间让newhead和newtail指向这块空间,使其成为首元节点(哨兵位),这样在插入时可以免去链表为空情况的判断,最后返回新链表的下一个节点即可。
哨兵位:数值域不存储有效数据,指针域存储有效地址

1.3代码

/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ typedef structListNode ListNode;structListNode*mergeTwoLists(structListNode* list1,structListNode* list2){ ListNode* newhead =(ListNode*)malloc(sizeof(ListNode)); ListNode* pcur1 = list1;; ListNode* pcur2 = list2; ListNode*newtail = newhead; newtail->next = NULL;while(pcur1 && pcur2){if(pcur1->val <= pcur2->val){ newtail->next = pcur1; newtail = newtail->next; pcur1 = pcur1->next;}else{ newtail->next = pcur2; newtail = newtail->next; pcur2 = pcur2->next;}}//为遍历完的链表直接接上新链表尾部节点if(pcur1) newtail->next = pcur1;if(pcur2) newtail->next = pcur2;return newhead->next;}

注:大家也可以free掉我们手动开辟的节点空间来养成良好的编程习惯,因为这是算法题,在程序执行完后会会自动回收笔者主要讲解思路,就不主动free但大家在写工程时不要的空间要及时释放养成良好编程习惯

二、分割链表

2.1题目

链接:分割链表

在这里插入图片描述

2.2 算法原理

创建两个新链表,list1和list2分别存放小于x和大于或等于x的节点,最后让list1的尾指针指向list2的第一个元素即可。
:list2作为新链表的后半部分,最后一个节点的next要及时置NILL,防止死循环
技巧:依旧可以使用哨兵位,并把哨兵位的next初始化为NULL可以避免合并时一条链表为空的特殊判断造成要写大量特判代码。

2.3代码

/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ typedef structListNode ListNode;structListNode*partition(structListNode* head,int x){if(head == NULL)return head;//指向小于x链表的头节点 ListNode* list1 =(ListNode*)malloc(sizeof(ListNode)); ListNode* tail1 = list1;//指向大于x链表的头节点 ListNode* list2 =(ListNode*)malloc(sizeof(ListNode)); ListNode* tail2 = list2;//防止单个节点链表出现非法解引用 list1->next = NULL; list2->next = NULL; ListNode* pcur = head;while(pcur){if(pcur->val < x){ tail1->next = pcur; tail1 = tail1->next;}else{ tail2->next = pcur; tail2 = tail2->next;} pcur = pcur->next;} tail1->next = list2->next;//防止死循环 tail2->next = NULL;return list1->next;}

注:大家也可以free掉我们手动开辟的节点空间来养成良好的编程习惯,因为这是算法题,在程序执行完后会会自动回收笔者主要讲解思路,就不主动free但大家在写工程时不要的空间要及时释放养成良好编程习惯

三、环形链表的约瑟夫问题

3.1题目

链接:环形链表的约瑟夫问题

在这里插入图片描述

3.2 算法原理

核心:利用循环链表 + 循环计数
定义一个指针v指尾节点,一个指针指向头结点,利用一个变量s来循环技术,当s == m时让h指向的当前元素出队即可

在这里插入图片描述

3.3代码

typedef structListNode ListNode;//创建节点 ListNode*BuyNode(int x){ ListNode* newnode =(ListNode*)malloc(sizeof(ListNode)); newnode->val = x; newnode->next = NULL;return newnode;}//创建环形链表 ListNode*CyclicList(int n){ ListNode* head =BuyNode(1); ListNode* tail = head;for(int i =2;i <= n;i++){ tail->next =BuyNode(i); tail = tail->next;} tail->next = head;return tail;}intysf(int n,int m ){ ListNode* prev =CyclicList(n); ListNode* phead = prev->next;int count =1;//计数while(phead != prev){if(count == m){ prev->next = phead->next;free(phead); phead = prev->next; count =1;}else{ prev = phead; phead = phead->next; count++;}}return phead->val;}

总结与每日励志

✨本文系统讲解了链表操作的三大经典题型:合并有序链表通过哨兵位简化插入逻辑,分割链表采用双链表分类处理,环形链表约瑟夫问题巧妙结合循环计数。每种解法均配有清晰的算法图解和完整代码实现,帮助读者深入理解链表操作的核心逻辑与实用技巧。掌握这些题型不仅能提升面试竞争力,更能培养扎实的数据结构思维。坚持每日练习,保持对算法的热情与专注,终将在编程之路上收获成长与突破。永远相信美好的事情即将发生!

在这里插入图片描述

Read more

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

摘要:本文聚焦OpenClaw从测试环境走向生产环境的核心痛点,围绕“性能优化、安全加固、监控运维”三大维度展开实操讲解。先明确生产环境硬件/系统选型标准,再通过硬件层资源管控、模型调度策略、缓存优化等手段提升响应速度(实测响应效率提升50%+);接着从网络、权限、数据三层构建安全防护体系,集成火山引擎安全方案拦截高危操作;最后落地TenacitOS可视化监控与Prometheus告警体系,配套完整故障排查清单和虚拟实战案例。全文所有配置、代码均经实测验证,兼顾新手入门实操性和进阶读者的生产级部署需求,帮助开发者真正实现OpenClaw从“能用”到“放心用”的跨越。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:

By Ne0inhk
ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》《STM32 HAL库专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言  一、实验基础说明 1.1、互斥体简介 1.2 本次实验设计思路 二、硬件原理分析(看过之前博客的可以忽略) 三、实验程序编写 3.1 互斥体 LED 驱动代码(mutex.c) 3.2.1、设备结构体定义(28-39

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

文章目录 * 前言 * make/makefile * 文件的三个时间 * Linux第一个小程序-进度条 * 回车和换行 * 缓冲区 * 程序的代码展示 * git指令 * 关于gitee * Linux调试器-gdb使用 * 作业部分 前言 做 Linux 开发时,你是不是也遇到过这些 “卡脖子” 时刻?写 makefile 时,明明语法没错却报错,最后发现是依赖方法行没加 Tab;想提交代码到 gitee,记不清 git add/commit/push 的 “三板斧”,还得反复搜教程;用 gdb 调试程序,输了命令没反应,才想起编译时没加-g生成 debug 版本;甚至连写个进度条,都搞不懂\r和\n的区别,导致进度条乱跳…… 其实这些问题,

By Ne0inhk