跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

单向链表六大核心操作详解:销毁、查找、倒置与排序

详细介绍单向链表的六大核心操作。包括销毁链表以释放内存,使用快慢指针法查找中间节点和倒数第 K 个节点,通过迭代法反转链表方向,实现冒泡与选择排序,以及检测链表是否存在环。代码示例基于 C 语言,涵盖节点定义、内存管理及关键逻辑实现,帮助读者理解指针操作与算法原理。

山野诗人发布于 2026/3/27更新于 2026/10/2186 浏览
单向链表六大核心操作详解:销毁、查找、倒置与排序

单向链表是数据结构中最基础也最常用的线性结构之一,由一系列节点组成。每个节点包含数据域存储数据和指针域存储下一个节点的地址,节点间通过指针串联形成链式结构。相比数组,链表插入删除高效,但随机访问需遍历。

一、单向链表的基本结构

定义链表节点结构是所有操作的基础。

#include <stdio.h>
#include <stdlib.h>

// 定义链表节点结构
typedef struct Node {
    int data; // 数据域
    struct Node* next; // 指针域
} Node;

// 创建新节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

节点通过 next 指针连接,最后一个节点的 next 为 NULL 表示链表结束。

二、单向链表的销毁

销毁链表需释放所有节点内存,避免内存泄漏。步骤为遍历链表并逐个释放节点。

void destroyList(Node** head) {
    if (head == NULL || *head == NULL) return;
    Node* current = *head;
    Node* nextNode;
    while (current != NULL) {
        nextNode = current->next;
        (current);
        current = nextNode;
    }
    *head = ;
}
free
NULL

销毁时需暂存下一个节点地址,传入头指针的地址以便将头节点设为 NULL。

三、查找中间节点

常用快慢指针法。快指针每次走 2 步,慢指针每次走 1 步,快指针到尾时,慢指针在中点。

Node* findMiddleNode(Node* head) {
    if (head == NULL || head->next == NULL) return head;
    Node* slow = head;
    Node* fast = head;
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

偶数长度时返回第一个中间节点。若需返回靠后的中间节点,可调整初始条件。

四、查找倒数第 K 个节点

双指针法。先让指针 p1 走 K 步,再 p1 和 p2 同步走,p1 到尾时 p2 为倒数第 K 个。

Node* findKthFromEnd(Node* head, int k) {
    if (head == NULL || k <= 0) return NULL;
    Node* p1 = head;
    Node* p2 = head;
    for (int i = 0; i < k; i++) {
        if (p1 == NULL) return NULL;
        p1 = p1->next;
    }
    while (p1 != NULL) {
        p1 = p1->next;
        p2 = p2->next;
    }
    return p2;
}

需注意 K 的合法性(K<=0 或 K>链表长度)。

五、链表的倒置

将链表方向反转,如 1->2->3 变为 3->2->1。常用迭代法(三指针)。

Node* reverseList(Node* head) {
    Node* prev = NULL;
    Node* curr = head;
    Node* next = NULL;
    while (curr != NULL) {
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

时间复杂度 O(n),空间 O(1)。递归法也可实现但易栈溢出。

六、链表的排序(冒泡与选择)

1. 冒泡排序

相邻节点比较交换,每轮将最大节点沉底。

void bubbleSortList(Node* head) {
    if (head == NULL || head->next == NULL) return;
    int swapped;
    Node* ptr;
    Node* last = NULL;
    do {
        swapped = 0;
        ptr = head;
        while (ptr->next != last) {
            if (ptr->data > ptr->next->data) {
                int temp = ptr->data;
                ptr->data = ptr->next->data;
                ptr->next->data = temp;
                swapped = 1;
            }
            ptr = ptr->next;
        }
        last = ptr;
    } while (swapped);
}

2. 选择排序

每轮找最小节点,与当前位置交换。

void selectionSortList(Node* head) {
    if (head == NULL || head->next == NULL) return;
    Node* curr = head;
    while (curr != NULL && curr->next != NULL) {
        Node* minNode = curr;
        Node* temp = curr->next;
        while (temp != NULL) {
            if (temp->data < minNode->data) minNode = temp;
            temp = temp->next;
        }
        if (minNode != curr) {
            int tempData = curr->data;
            curr->data = minNode->data;
            minNode->data = tempData;
        }
        curr = curr->next;
    }
}

链表排序可直接交换数据(简单)或交换节点(复杂)。

七、判断链表是否有环

快慢指针法。快指针每次 2 步,慢指针每次 1 步,相遇则有环。

int hasCycle(Node* head) {
    if (head == NULL || head->next == NULL) return 0;
    Node* slow = head;
    Node* fast = head;
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) return 1;
    }
    return 0;
}

若有环,快指针会追上慢指针;若无环,快指针先到尾。时间复杂度 O(n),空间 O(1)。

总结

单向链表核心操作围绕指针 manipulation 展开。销毁释放内存,快慢指针解决中间/倒数第 K/环检测,迭代反转链表,冒泡选择排序链表。掌握这些操作需理解指针指向变化,多画图模拟过程,结合实际示例调试代码,方能融会贯通。链表是更复杂结构的基础,务必扎实掌握。

目录

  1. 一、单向链表的基本结构
  2. 二、单向链表的销毁
  3. 三、查找中间节点
  4. 四、查找倒数第 K 个节点
  5. 五、链表的倒置
  6. 六、链表的排序(冒泡与选择)
  7. 1. 冒泡排序
  8. 2. 选择排序
  9. 七、判断链表是否有环
  10. 总结

更多推荐文章

查看全部
  • Spring 核心技术解析:Spring-Jcl 日志模块详解
  • JavaScript 实现 BFS 广度优先搜索算法及可视化演示
  • 动态规划入门:多状态 DP 问题实战(打家劫舍与股票买卖)
  • 【面试分享】前端 React 50个基础高频面试题,助你轻松拿 offer!
  • Linux 进程控制:自主 Shell 命令行解释器实现
  • 本地服务器部署Text generation并添加code llama实现远程多人协作
  • 基于 WebSocket 的外汇实时数据接入方案
  • AutoDL 服务器系统盘空间清理指南
  • 动态规划路径类 DP 入门:3 道经典例题解析
  • C++ 标准库:map 与 set 容器详解与实战
  • 4GB 显存限制下构建 LLM 基础开发环境指南
  • Rokid 灵珠平台搭建旅游 AR 智能体实战指南
  • Harness Engineering:给 AI 套上缰绳的工程学
  • Flutter Web 跨域(CORS)本地调试方案
  • 《Agent Runtime 工程化》第六章 MCP 与 Provider 抽象:6.3 把 MCP 工具接入 Registry
  • 知网 AIGC 检测算法 3.0 升级要点与应对策略
  • Gemini AI 生成图片水印去除方法与技术解析
  • Python 基础入门:标识符、关键字与基本语句详解
  • Spring AI MCP Server 集成与示例
  • 未来 10 年值得关注的 5 个高薪行业

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online