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

单向链表的排序

排序是数据结构的核心算法而链表排序更是面试高频考点 —— 因为链表无法随机访问需要用指针操作来实现排序逻辑。本文将从插入排序的核心思想讲起一步步拆解数组插入排序 → 单向链表插入排序 → 单向链表选择排序用图文 代码带你彻底掌握链表排序的精髓。一、插入排序核心思想与数组实现1.1 插入排序的核心思想插入排序的本质是 **「将无序区的数据逐个插入到有序区的合适位置」**最终让整个序列有序。可以类比军训排队一开始只有第一个人站好有序区后面的人无序区依次过来找到自己在队伍中的位置插入进去重复这个过程直到所有人都站成有序队列。1.2 数组实现插入排序数组的插入排序逻辑清晰是理解链表插入排序的基础// 数组插入排序升序 void insert_sort(int a[], int len) { int j, t; // step1: 划分有序区/无序区i从1开始默认a[0]是有序区 for (int i 1; i len; i) { // step2: 拿数取出无序区第一个元素a[i] t a[i]; j i; // step3: 找位置在有序区中找到t的插入位置 while (j 0 t a[j-1]) { a[j] a[j-1]; // 元素后移腾出位置 --j; } // step4: 插入将t放到正确位置 a[j] t; } }执行步骤拆解初始有序区[a[0]]无序区[a[1], a[2], ..., a[n-1]]取出无序区第一个元素t从后往前遍历有序区比t大的元素后移将t插入到腾出的位置有序区长度 1重复直到无序区为空。二、单向链表插入排序从数组到链表的思维转换链表无法随机访问也不能像数组那样「后移元素」所以插入排序的实现逻辑完全不同 ——核心是「拆分链表 逐个插入有序区」。2.1 链表插入排序的整体流程以链表4 → 2 → 3 → 5为例完整流程如下阶段操作链表状态初始原链表head → 4 → 2 → 3 → 5 → NULLstep1拆分有序区 / 无序区有序区head → 4 → NULL无序区2 → 3 → 5 → NULLstep2拿数取无序区第一个节点2有序区head → 4 → NULL待插入2无序区3 → 5 → NULLstep3找位置2 4插在4前面有序区head → 2 → 4 → NULLstep4拿数取无序区第一个节点3有序区head → 2 → 4 → NULL待插入3无序区5 → NULLstep5找位置2 3 4插在2和4之间有序区head → 2 → 3 → 4 → NULLstep6拿数取无序区第一个节点5有序区head → 2 → 3 → 4 → NULL待插入5无序区NULLstep7找位置5 4插在末尾有序区head → 2 → 3 → 4 → 5 → NULL排序完成2.2 关键概念与指针设计p_list指向有序区的头节点p_temp指向无序区的第一个节点用于遍历无序区p_insert当前要插入到有序区的节点p在有序区中遍历的指针最终停在待插入位置的前一个节点链表插入必须知道前驱节点。2.3 链表插入排序代码实现#include stdio.h #include stdlib.h // 定义链表节点 typedef struct node { int data; struct node *next; } node_t; // 创建头节点 node_t *create_list() { node_t *head (node_t *)malloc(sizeof(node_t)); head-data 0; // 头节点不存有效数据 head-next NULL; return head; } // 尾插法添加节点 void append(node_t *head, int data) { node_t *new_node (node_t *)malloc(sizeof(node_t)); new_node-data data; new_node-next NULL; node_t *p head; while (p-next ! NULL) { p p-next; } p-next new_node; } // 打印链表 void print_list(node_t *head) { node_t *p head-next; while (p ! NULL) { printf(%d , p-data); p p-next; } printf(\n); } // 单向链表插入排序升序 void insert_sort_list(node_t *p_list) { if (p_list-next NULL || p_list-next-next NULL) { return; // 空链表或只有一个节点无需排序 } // step1: 拆分有序区和无序区 node_t *p_temp p_list-next-next; // 无序区第一个节点 p_list-next-next NULL; // 断链有序区只剩第一个节点 // step2: 遍历无序区逐个插入有序区 while (p_temp ! NULL) { node_t *p_insert p_temp; // 待插入节点 p_temp p_temp-next; // 无序区指针后移 // step3: 在有序区中找插入位置p最终停在待插入位置的前驱 node_t *p p_list; while (p-next ! NULL p-next-data p_insert-data) { p p-next; } // step4: 插入节点 p_insert-next p-next; p-next p_insert; } } int main() { node_t *head create_list(); // 构造测试链表4 → 2 → 3 → 5 append(head, 4); append(head, 2); append(head, 3); append(head, 5); printf(排序前); print_list(head); insert_sort_list(head); printf(排序后); print_list(head); // 输出2 3 4 5 return 0; }代码核心逻辑拆分链表将原链表拆为「有序区仅首节点」和「无序区剩余节点」遍历无序区逐个取出待插入节点寻找位置用指针p遍历有序区找到待插入节点的前驱插入节点修改指针将待插入节点链入有序区。三、单向链表选择排序另一种经典排序思路选择排序的核心是 **「为每个位置选择合适的数」**—— 在无序区中找到最小或最大的节点将其交换到当前位置逐步让链表有序。3.1 选择排序的核心思想类比军训排队从第一个位置开始在后面所有人中找到最矮的人交换到第一个位置再从第二个位置开始在后面所有人中找到最矮的人交换到第二个位置重复直到所有位置都处理完毕。3.2 链表选择排序代码实现// 单向链表选择排序升序 void select_sort_list(node_t *p_list) { if (p_list-next NULL || p_list-next-next NULL) { return; } node_t *curr p_list-next; // 当前要确定的位置 while (curr ! NULL) { node_t *p curr-next; // 遍历指针 node_t *min_node curr; // 记录当前最小节点 // 在无序区中找到最小节点 while (p ! NULL) { if (p-data min_node-data) { min_node p; // 更新最小节点 } p p-next; } // 交换当前节点和最小节点的数据简化实现无需修改指针 if (min_node ! curr) { int temp curr-data; curr-data min_node-data; min_node-data temp; } curr curr-next; // 处理下一个位置 } }代码核心逻辑定位当前位置curr指向当前要确定的位置寻找最小值遍历curr之后的节点找到数据最小的节点交换数据将curr节点和最小节点的数据交换简化实现避免复杂指针操作后移指针curr后移处理下一个位置。四、链表排序对比插入排序 vs 选择排序特性插入排序选择排序核心思想逐个插入有序区为每个位置选最小数时间复杂度最好O (n)已排序最坏 / 平均O (n²)最坏 / 平均O (n²)空间复杂度O (1)原地排序O (1)原地排序稳定性稳定相同元素相对位置不变不稳定交换可能破坏相对位置链表实现难度中等需拆分链表 找前驱简单直接交换数据使用建议链表已接近有序 → 优先用插入排序时间复杂度接近 O (n)追求实现简单 → 用选择排序数据交换逻辑清晰大规模数据 → 不建议用这两种应使用归并排序链表排序最优算法时间复杂度 O (nlogn)。五、总结与学习建议5.1 核心知识点回顾插入排序将无序区元素逐个插入有序区数组版靠「后移元素」链表版靠「指针插入」链表插入排序关键是「拆分链表」和「找到前驱节点」是面试高频考点选择排序为每个位置选最小数链表实现可通过「交换数据」简化指针操作时间复杂度两种排序均为 O (n²)适合小规模数据。5.2 学习建议先练数组版理解插入排序的核心思想再迁移到链表画图理解用草稿纸画出指针变化过程比死记代码更有效边界测试测试空链表、单节点链表、已排序链表、逆序链表覆盖所有边界情况进阶学习掌握这两种后可尝试学习链表归并排序。

相关文章:

单向链表的排序

排序是数据结构的核心算法,而链表排序更是面试高频考点 —— 因为链表无法随机访问,需要用指针操作来实现排序逻辑。本文将从插入排序的核心思想讲起,一步步拆解数组插入排序 → 单向链表插入排序 → 单向链表选择排序,用图文 代…...

华为交换机日常运维:5个必会的端口状态查询命令(含display interface brief详解)

华为交换机端口状态深度解析:从基础查询到实战排障 清晨7:30,机房告警灯突然闪烁——核心业务端口异常离线。作为网络运维工程师,如何在十分钟内定位问题?掌握端口状态查询命令不仅是基础技能,更是快速响应故障的第一道…...

戴森吸尘器电池管理固件升级终极方案:开源固件深度解析与实战指南

戴森吸尘器电池管理固件升级终极方案:开源固件深度解析与实战指南 【免费下载链接】FU-Dyson-BMS (Unofficial) Firmware Upgrade for Dyson V6/V7 Vacuum Battery Management System 项目地址: https://gitcode.com/gh_mirrors/fu/FU-Dyson-BMS 戴森V6/V7系…...

SeqGPT-560M嵌入式开发:卓晴教授案例研究

SeqGPT-560M嵌入式开发:卓晴教授案例研究 1. 引言 在嵌入式设备上运行大语言模型一直是个技术挑战,特别是对于资源受限的边缘计算场景。卓晴教授团队最近成功将SeqGPT-560M模型部署到嵌入式平台,实现了在低功耗设备上进行高质量的文本理解任…...

别再为Moonlight/SteamLink串流失败头疼了!深入理解Windows会话管理与tscon命令的妙用

深入解析Windows会话管理:解锁Moonlight/SteamLink串流的技术奥秘 当你沉浸在Moonlight或SteamLink的游戏串流体验中,突然遭遇"远程PC已锁定"的提示,这种中断不仅令人沮丧,更暴露了Windows会话管理的复杂性。本文将带你…...

3/18打卡

...

GOM传奇引擎外网架设避坑指南:常见问题与解决方案

GOM传奇引擎外网架设避坑指南:常见问题与解决方案 1. 外网架设前的关键准备工作 很多开发者在开始GOM引擎外网架设时,常常因为基础环境配置不当导致后续问题频发。这里分享几个容易被忽视但至关重要的准备环节: 硬件与网络环境检查清单&#…...

Google Agent Development Kit (ADK) 指南 第二章:环境搭建与快速开始

Google Agent Development Kit (ADK) 指南 第二章:环境搭建与快速开始 系列教程:这是《Google ADK 指南》系列的第二章。 前置知识:已完成第一章,了解 ADK 基本概念。 目录 前置要求GCP 账号配置ADK 安装第一个 Agent 应用本地调…...

EVODiff:重新定义扩散模型推理范式的突破性探索

EVODiff:重新定义扩散模型推理范式的突破性探索 【免费下载链接】diffusers-cd_imagenet64_lpips 项目地址: https://ai.gitcode.com/hf_mirrors/openai/diffusers-cd_imagenet64_lpips 一、问题:扩散模型的"阿喀琉斯之踵"何在&#x…...

从太空到地面:详解J2000与WGS84坐标系在遥感卫星任务中的协同与转换

1. 为什么遥感卫星需要两套坐标系? 当你用手机地图导航时,有没有想过卫星是如何精确知道你和目标位置的关系的?这背后其实隐藏着一个关键问题:太空中高速飞行的卫星(每秒约7公里)和地面静止的建筑物&#…...

3个步骤释放AI科研助手潜力:自动化论文生成与智能文献分析提升科研效率

3个步骤释放AI科研助手潜力:自动化论文生成与智能文献分析提升科研效率 【免费下载链接】AI-Researcher "AI-Researcher: Fully-Automated Scientific Discovery with LLM Agents" & "Open-Sourced Alternative to Google AI Co-Scientist"…...

手把手教你用V-REP(CoppeliaSim)在Ubuntu20.04上搭建第一个机器人仿真项目

从零开始:Ubuntu 20.04下CoppeliaSim机器人仿真实战指南 在机器人技术快速发展的今天,仿真平台已成为开发者验证算法、测试设计的必备工具。CoppeliaSim(原V-REP)作为一款功能强大且开源的机器人仿真软件,凭借其跨平台…...

如何在30分钟内快速搭建企业级权限管理系统:RuoYi-Vue实战指南

如何在30分钟内快速搭建企业级权限管理系统:RuoYi-Vue实战指南 【免费下载链接】RuoYi-Vue 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 …...

Qt 树形数据实战:从QAbstractItemModel到QTreeView的完整实现

1. Qt树形数据管理基础 在Qt框架中处理树形数据是个常见需求,比如文件浏览器、组织结构图或者配置项管理。我刚开始接触Qt时,最头疼的就是理解Model/View架构,特别是当需要自定义数据结构时。后来发现只要掌握几个关键点,就能轻松…...

奇安信天眼实战:从协议字段到告警分析的完整指南(附常见漏洞案例)

奇安信天眼实战:从协议字段到告警分析的完整指南(附常见漏洞案例) 在企业安全运维的日常工作中,高效识别和响应潜在威胁是每个安全工程师的核心任务。奇安信天眼系统作为国内领先的威胁检测与响应平台,其强大的协议分析…...

革新性微信协议交互引擎:构建企业级智能消息处理系统

革新性微信协议交互引擎:构建企业级智能消息处理系统 【免费下载链接】puppet-xp Wechaty Puppet WeChat Windows Protocol 项目地址: https://gitcode.com/gh_mirrors/pu/puppet-xp 在数字化办公与即时通讯深度融合的今天,企业级消息自动化处理面…...

GLM-Image WebUI惊艳案例分享:数字艺术、写实人像、概念设计作品集

GLM-Image WebUI惊艳案例分享:数字艺术、写实人像、概念设计作品集 1. 开启AI艺术创作新篇章 想象一下,你只需要用文字描述心中的画面,就能在几分钟内看到它变成精美的图像。这不是科幻电影的情节,而是GLM-Image WebUI带给我们的…...

华为eNSP模拟器实战:通过Telnet实现AC远程管理的AAA认证配置详解

1. 华为eNSP模拟器与AC远程管理基础 第一次接触华为eNSP模拟器时,我被它高度还原真实设备操作体验的特性惊艳到了。这个免费的模拟器不仅能完整模拟华为路由器、交换机等网络设备,还能搭建包含AC(接入控制器)和AP(接入…...

在 Windows 10 上安装 AMD APP SDK 3.0 (64 bits)

在 Windows 10 上安装 AMD APP SDK 3.0 {64 bits}1. AMD APP SDK Installer 3.0 for Windows 64 bits2. D:\Program Files\AMD APP SDK\3.0\References1. AMD APP SDK Installer 3.0 for Windows 64 bits AMD-APP-SDKInstaller-v3.0.130.135-GA-windows-F-x64.exe 解除锁定 C…...

Adobe力推的Gain Map到底是什么?一篇看懂它如何用一张图搞定HDR和SDR兼容

Gain Map技术解析:如何用一张图实现HDR与SDR的完美兼容 当你在社交媒体分享一张夕阳照片时,是否遇到过这样的困扰——手机上看到的绚丽色彩在朋友的老款显示器上变得平淡无奇?这种显示效果的不一致性,正是当前图像技术面临的核心挑…...

python基础学习笔记第五章

一、数据容器入门1. 定义一种可容纳多份数据的Python数据类型,每份数据为元素,元素可以是任意类型(字符串、数字、布尔等)。2. 分类(按特性划分)依据是否支持重复元素、是否可修改、是否有序分为5类&#x…...

HPatches数据集实战:从特征点检测到匹配精度的全链路评估

1. HPatches数据集入门指南 第一次接触HPatches数据集时,我和大多数开发者一样有点懵。这个在特征点检测领域赫赫有名的基准测试集,到底该怎么用才能发挥最大价值?经过几个项目的实战,我总结出了一套小白也能快速上手的方法。 HPa…...

MATLAB R2023b安装包下载及安装步骤说明

MATLAB安装教程 1.打开下载好的MATLAB2023b文件包,解压Windouw版本的MATLAB里面包含了三个文件,如图所示: 2.选择上述文件中的R2023b_-Windows.iso文件,右键点击选择装载,如下图所示: 装载好后的文件如下…...

Python爬虫进阶:自动化采集语音训练数据实战

Python爬虫进阶:自动化采集语音训练数据实战 1. 引言 语音合成技术的快速发展对高质量训练数据提出了巨大需求。以Qwen3-TTS为例,仅需3秒参考音频就能实现高精度音色克隆,但前提是需要大量优质的语音-文本配对数据。传统的手工采集方式效率…...

AutoDock Vina硼原子兼容性实战指南:解决1.1.2+版本特殊原子对接问题

AutoDock Vina硼原子兼容性实战指南:解决1.1.2版本特殊原子对接问题 【免费下载链接】AutoDock-Vina AutoDock Vina 项目地址: https://gitcode.com/gh_mirrors/au/AutoDock-Vina 诊断硼原子对接失败问题 作为一名计算药物学家,我最近在处理含硼…...

Gemma-3-12b-it图文问答典型错误分析:光照/遮挡/低分辨率应对策略

Gemma-3-12b-it图文问答典型错误分析:光照/遮挡/低分辨率应对策略 1. 工具概述 Gemma-3-12b-it是一款基于Google Gemma-3-12b-it大模型开发的多模态交互工具,专为本地图文问答场景优化。该工具通过全维度CUDA性能优化,支持图片上传与文本提…...

当AI学会“鉴谎”:企业舆情处置从被动救火到主动防御

最近跟几个做品牌公关的朋友聊天,发现大家都有一个共同的焦虑:网络上的信息传播太快了,一条负面视频、一篇恶意差评,可能一夜之间就让企业多年积累的声誉受到重创。更棘手的是,传统处置方式要么慢如蜗牛,要…...

快速体验SenseVoice语音识别:带量化ONNX模型一键启动服务

快速体验SenseVoice语音识别:带量化ONNX模型一键启动服务 1. 语音识别服务简介 SenseVoice是一款基于ONNX量化的多语言语音识别服务,特别适合需要快速部署和高效推理的开发场景。这个经过优化的模型能够在保持高精度的同时,显著降低资源消耗…...

Windows 基本操作快捷键

Windows 基本操作快捷键1. Windows 7 专业版2. Keyboard shortcuts in WindowsReferences1. Windows 7 专业版 2. Keyboard shortcuts in Windows Win 键是键盘上图标像窗户键。 快速切换窗口 Alt Tab 快速移到网页末 Ctrl End 快速移到网页首 Ctrl Home 锁屏 Win …...

100激光只是起步,易加增材把金属3D打印机做到3米级,全球最大!

易加增材:没有最大,只有更大。EP-M3050金属3D打印设备当前,金属3D打印正加快向大尺寸、一体化、高精度、高效率方向发展,航空航天、能源装备等领域对超大尺寸、多激光金属增材制造设备的需求持续上升。在此背景下,易加…...