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

数据结构:单链表的头插/尾插及头删/尾删操作

阐述了数据结构基本概念及算法特性,重点演示了单链表在 C 语言中的实现。内容包括创建、销毁、头插、尾插、头删、尾删、查找、打印及计算长度等操作,通过具体代码示例解析了指针操作与内存管理细节。

奶糖兔发布于 2026/3/23更新于 2026/10/2120K 浏览

一、数据结构基础概念

程序=数据结构 + 算法。

数据结构:数据的结构。数据 = 元素之间的关系 = 数据的组织方式。

算法 = 数据元素之间的相互作用的操作(运算)。

  1. 数据:是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别并输入给计算机处理的符号集合。
  2. 数据对象:性质相同的数据元素的集合。
  3. 数据元素:是组成数据的、有一定意义的基本单位,在计算机中通常作为整体处理,也被称为记录。
  4. 数据项:是数据不可分割的最小单位。

文章配图

数据结构研究的是数据元素之间的关系。

二、数据结构分为逻辑结构和物理结构

逻辑关系:逻辑上存在一种联系; 物理结构 (关系):存储到计算机中的结构。

**逻辑结构:**数据元素之间无关联的集合。

  • 线性结构(特点:除了第一个元素和最后一个元素之外其余元素都只有一个前驱和后继);
  • 树:目录层次结构一对多关系;
  • 图:地图地点---图的结构多对多关系。

物理结构:指存储方式,如顺序存储(数组)和链式存储(指针)。

计算机本身的存储结构-------线性。 计算机的线性存储空间中表示不同的逻辑机构。

存储结构:

**顺序结构:**用一片连续的内存空间存放数据。对应到 C 语言数组 (单一性,有序性,连续性)----- 数据结构-------顺序表。 特点:访问数据方便 O(1),插入删除不方便 O(n)。

**链式结构:**通过指针指向下一个元素。也可以用来表示一种线性关系彼此联系起来 eg:铁链 特点:访问数据需要遍历 O(n),插入删除方便 O(1)。

**索引结构:**找---【索引表 (有序)】-----数据 eg:查字典,书目录。

**散列(哈希)结构:**找(key)------【散列结构 (无序)】------计算在哪里。

文章配图

算法 5 个基本特性:输入,输出,有穷性,确定性和可行性。 设计算法:正确性,健壮性,可读性,时间和空间效率。

算法效率的度量:

**时间复杂度(更重要):**时间复杂度用于衡量算法执行时间随输入规模增长的变化趋势。常见的表示方法为大 O 符号(O),描述最坏情况下算法的增长上限。(最好,最坏,平均)

**空间复杂度:**空间复杂度用于衡量算法在运行过程中临时占用存储空间的大小随输入规模增长的变化趋势。同样使用大 O 符号表示。

非原地插入排序 O(n);原地插入排序 O(1);

三、学习数据结构

线性表:顺序表---以顺序结构存储的线性表(数组);链表----以链式结构存储的线性表。

链表:
  1. 数据元素-----节点 {数据---数据域 联系-----指针域}
  2. 头节点------数据部分不关心-----只是为了方便操作链表,链表---都是有头链表
  3. 尾节点的指针域为空 NULL;

代码的实现:创建(增删改查),销毁。 链表:1.创建空列表 2.销毁链表 3.增数据--插入 4.删数据---删除;5.查数据---找值;6.改数据----改值

//结构体 struct node { int data;//要处理的数据是 int 类型的数据 struct node *pnext;//指向下一个节点 }

数据插入到链表:

文章配图

1.头插法

step1.创建了一个新节点并且给值
step2.新节点指向原先首节点
p_new->pnext=phead->pnext
step3.将头节点指向新节点
phead->pnext=p_new;

#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
    data_t data;
    struct node *pnext;
}node_t;

node_t *create_linklist(void) {
    node_t *head = malloc(sizeof(node_t));//在堆上开空间不用传参不会自动销毁
    if(head == NULL) {
        printf("malloc fail");
        return NULL;
    }
    head->pnext = NULL;//头节点指针域为空
    return head;
}

void linklist_insert_head(node_t *phead, data_t data) //插入一个新的节点
{
    node_t *p_new = malloc(sizeof(node_t)); //创建新节点
    if(phead == NULL) //开空间可能失败
    {
        printf("malloc fail");
        return;
    }
    p_new->data = data; //传入数据
    p_new->pnext = NULL; //指针域给空(可写可不写)
    //连接链表
    p_new->pnext = phead->pnext; //插入,指向头节点所指的指针域
    phead->pnext = p_new; //头节点指向新节点
}

int is_empty(node_t *phead) //判断链表是否为空
{
    return phead->pnext == NULL;
}

int length(node_t *phead)
{
    if(is_empty(phead) == 1)
    {
        return 0;
    }
    int i = 0;
    node_t *p = phead->pnext;
    while(p!=NULL)
    {
        i++;
        p = p->pnext;
    }
    return i;
}

void linklist_print(node_t *phead) //打印链表
{
    if(is_empty(phead) == 1)
    {
        printf("empty linklist\n");
        return;
    }
    node_t *p = phead->pnext; //头节点之后的节点指针域
    while(p!=NULL)
    {
        printf("%d ",p->data); //打印数据域
        p = p->pnext; //指向链表下一个指针域
    }
    putchar('\n');
}

int main()
{
    node_t *phead = create_linklist();
    linklist_insert_head(phead,4);
    linklist_insert_head(phead,3);
    linklist_insert_head(phead,2);
    linklist_insert_head(phead,1);
    linklist_print(phead);
    int i = length(phead);
    printf("i = %d ",i);
    return 0;
}
查----遍历---打印

遍历打印逐个节点访问:

step1.指针遍历 p ; p->pnext != NULL //后面还有节点继续往后

2.尾插法

stepl.创建了一个新节点并且给值
p_new->pnext=NULL;
step2.找到尾节点 p 初始位置就从头节点开始判断 p 的指针域是否为 NULL
p->pnext != NULL
step3.链接
p->pnext=p_new

void linklist_insert_tail(node_t *phead, data_t data) {
    node_t *p_new = malloc(sizeof(node_t));
    if(p_new == NULL) //判断链表是不是空
    {
        printf("%smalloc fail\n", __func__);
        return;
    }
    p_new->data = data;
    p_new->pnext = NULL;//必须有
    node_t *p = phead;
    while(p->pnext != NULL)
    {
        p = p->pnext;
    }
    p->pnext = p_new; //连接
}
找值:从头遍历
node_t *linklist_find_key(node_t *phead, data_t key) {
    if(is_empty(phead) == 1)
    {
        return NULL;
    }
    node_t *p = phead->pnext;
    while(p != NULL)
    {
        if(p->data == key)
        {
            return p;
        }
        p = p->pnext;
    }
    return NULL;
}
3.删除:头删,尾删

头删

//判断链表是否为空
step1.有一个指针变量指向首节点 phead->pnext
step2.让头节点指向 p->pnext
step3.释放 p 所在的节点 free(p);

void linklist_delete_head(node_t *phead) {
    if(is_empty(phead) == 1)
    {
        return;
    }
    node_t *p = phead->pnext;
    phead->pnext = p->pnext;
    free(p);
}

尾删

//判断链表为空--空直接返回
s1.找到尾节点前一个节点
//统一操作逻辑 p 的初值得从 phead 开始
p->pnext->pnext == NULL
s2.释放尾节点 free(p->pnext)
s3.将前一个节点,设置为新的尾节点 p->pnext=NULL

void linklist_delete_tail(node_t *phead) {
    if(is_empty(phead) == 1)
    {
        printf("empty linklist\n");
        return;
    }
    node_t *p = phead;
    while(p->pnext->pnext != NULL)
    {
        p = p->pnext;
    }
    free(p->pnext);
    p->pnext = NULL;
}

目录

  1. 一、数据结构基础概念
  2. 二、数据结构分为逻辑结构和物理结构
  3. 存储结构:
  4. 算法效率的度量:
  5. 三、学习数据结构
  6. 链表:
  7. 1.头插法
  8. 查----遍历---打印
  9. 2.尾插法
  10. 找值:从头遍历
  11. 3.删除:头删,尾删

更多推荐文章

查看全部
  • macOS 安装 Claude Code 完整教程
  • 大模型技术详解:定义、架构与核心应用场景
  • 第十六届极客大挑战 Web 安全题目复现与解析
  • OpenClaw 集成飞书机器人实战指南
  • 零基础 CTF 学习完整指南
  • AI 绘画提示词参数设置与生成效果实战指南
  • FlashTable 实测:AI 赋能低代码开发与企业级应用构建
  • AI 应用:LLM 在工业领域的十大应用场景
  • C++ STL List 容器详解与模拟实现
  • 基于改进 YOLOv11n 的无人机红外目标检测算法
  • C++ 继承实战:从语法细到员工管理系统
  • 2026 年免费及低成本 AI 算力渠道指南与 OpenClaw 配置
  • 知网 AIGC 检测率过高应对策略与实践
  • Windows11 安装 Ubuntu 24.04.2 虚拟机教程(VMware 17.6.1)
  • Windows 11 Docker Desktop 安装与配置指南
  • Aurora 8B/10B 配置实战:从物理层到共享逻辑的避坑笔记
  • Nano Banana 生成中文模糊?用 Seedream 4.5 重绘文字提升清晰度
  • 深度感知 AI 应用:MiDaS 在虚拟现实中的部署案例
  • 基于 LLaMA-Factory 的大模型部署与微调实战
  • RISC-V处理器设计笔记:Verilog RTL与FPGA原型验证

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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