带头结点 的单链表插入方法(头插法与尾插法)

news2025/4/17 4:51:24

带头结点的单链表插入方法(头插法与尾插法)

在这里插入图片描述

在单链表的操作中,插入是最常见的操作之一,本文介绍 带头结点的单链表 如何实现 后插法前插法(包括 插入法后插数据交换法),并提供完整的 C++ 代码示例。


1. 链表的基本结构

带头结点 的单链表中,头结点 L 仅作为占位符,不存储数据,链表的数据从 L->next 开始。

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

typedef struct Node {
    int data;
    struct Node* next;
} Node, *List;
  • data:存储节点数据。
  • next:指向下一个节点的指针。
  • List:定义指向 Node 的指针类型,表示链表。

2. 链表初始化

bool Init(List &L) {
    L = (Node *)malloc(sizeof(Node));  // 创建头结点
    L->next = NULL;
    return true;
}
  • L 作为头结点,仅占位,不存储数据。
  • L->next = NULL 表示链表为空。

3. 后插法(在指定位置后插入)

3.1 后插法介绍

后插法 是指在 某个指定位置 i 之后 插入新的节点,即:

原链表: A -> B -> C -> NULL
插入后: A -> B -> X -> C -> NULL (X 插入到 B 之后)

3.2 后插法代码

bool Insert(List &L, int i, int value) {
    Node *p = L;  // p 指向头节点
    int j = 0;

    // 找到 i-1 位置的节点
    while (p != NULL && j < i - 1) {  
        p = p->next;  
        j++;
    }

    if (p == NULL) { // 如果 i 超出链表长度,插入失败
        return false;
    }

    // 创建新节点
    Node *s = (Node *)malloc(sizeof(Node));
    s->data = value;

    // 插入
    s->next = p->next;
    p->next = s;

    return true;
}

3.3 代码解析

  1. 找到 i-1 位置的节点
    • 通过 while 循环找到第 i-1 个节点 p,使 p->next 指向新节点。
  2. 创建新节点 s
    • 分配内存,存入 value
  3. 新节点 s 指向 p->next
    • s->next = p->next,让新节点连接到 p 的下一个节点。
  4. p 连接到 s
    • p->next = s,完成插入。

3.4 运行示例

void PrintList(List L) {
    Node *p = L->next;  // 跳过头节点
    while (p != NULL) {
        printf("%d -> ", p->data);
        p = p->next;
    }
    printf("NULL\n");
}

int main() {
    List L;
    Init(L);

    Insert(L, 1, 10);
    Insert(L, 2, 20);
    Insert(L, 3, 30);

    PrintList(L);
    return 0;
}
运行结果
10 -> 20 -> 30 -> NULL

4. 后插法实现前插法(交换数据法)

4.1 介绍

前插法 是指在 某个指定位置 i 之前 插入新节点:

原链表: A -> B -> C -> NULL
插入后: A -> X -> B -> C -> NULL (X 插入到 B 之前)

如果我们仍然使用后插法,可以通过 交换数据 来模拟前插效果:

  1. 找到 i 位置的节点 p
  2. 使用后插法p 后面 插入一个新节点 s
  3. 交换 psdata,这样 p 的数据变成新插入的数据,而 s 变成原 p 的数据。

当然 这里也可以使用 直接插入法 不过 需要从头 遍历链表 至其前驱结点 ,这里没有实现

4.2 代码

bool Insert(List &L, int i, int value) {
    if (i < 1) return false;

    Node *p = L;
    int j = 0;

    // 找到第 i 个位置的节点 p
    while (p->next != NULL && j < i - 1) {  
        p = p->next;
        j++;
    }

    if (p == NULL) return false;

    // 使用后插法创建新节点 s
    Node *s = (Node *)malloc(sizeof(Node));
    s->data = value;
    s->next = p->next;
    p->next = s;

    // **交换数据**,实现前插效果
    int temp = p->data;
    p->data = s->data;
    s->data = temp;

    return true;
}

4.3 运行示例

int main() {
    List L;
    Init(L);

    Insert(L, 1, 10);
    Insert(L, 2, 20);
    Insert(L, 3, 30);
    Insert(L, 2, 15); // 插入 15 到第 2 个位置

    PrintList(L);
    return 0;
}
输出
10 -> 15 -> 20 -> 30 -> NULL

15 被正确插入到了 20 之前,达到了前插的效果


5. 总结

后插法前插法(交换数据法)
插入方式i 个节点 之后插入i 个节点 之前插入
链表变化A -> B -> X -> CA -> X -> B -> C
i=1 时的情况头结点不变,只插入到 L->next 之后头结点改变,新节点变成 L
适用场景常用于 顺序插入,如尾插法适用于 倒序插入,如头插法
优点逻辑清晰,适用于大多数情况结构不变,适用于数据交换优化

两种插入方式的使用场景不同,在 动态链表管理 中,后插法适合 正常数据流,前插法适合 逆序处理


6. 参考代码完整示例

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

typedef struct Node {
    int data;
    struct Node* next;
} Node, *List;

bool Init(List &L) {
    L = (Node *)malloc(sizeof(Node));
    L->next = NULL;
    return true;
}

bool Insert(List &L, int i, int value) {
    if (i < 1) return false;

    Node *p = L;
    int j = 0;

    while (p->next != NULL && j < i - 1) {  
        p = p->next;
        j++;
    }

    if (p == NULL) return false;

    Node *s = (Node *)malloc(sizeof(Node));
    s->data = value;
    s->next = p->next;
    p->next = s;

    int temp = p->data;
    p->data = s->data;
    s->data = temp;

    return true;
}

希望本文能帮助新手更好地学习C++链表的学习!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Opencv之dilib库:表情识别

一、简介 在计算机视觉领域&#xff0c;表情识别是一个既有趣又具有挑战性的任务。它在人机交互、情感分析、安防监控等众多领域都有着广泛的应用前景。本文将详细介绍如何使用 Python 中的 OpenCV 库和 Dlib 库来实现一个简单的实时表情识别系统。 二、实现原理 表情识别系统…

基于web的生产过程执行管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 随着世界经济信息化、全球化的到来和电子商务的飞速发展&#xff0c;推动了很多行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、畅通、高效的线上管理系统。当前的生产过程执行管理存在管理效率…

C++:继承+菱形虚拟继承的一箭双雕

目录 一、继承概念与定义 1.1、什么是继承&#xff1f; 1.2、继承定义 二、继承关系与访问限定符 2.1、继承方式 三、基类与派生类对象的赋值转换 3.1、向上转型 3.2、对象切片 四、继承中的作用域 4.1、隐藏 五、派生类中的成员函数 5.1、构造与析构 六、继承与友…

网络:华为数通HCIA学习:静态路由基础

文章目录 前言静态路由基础静态路由应用场景 静态路由配置静态路由在串行网络的配置静态路由在以太网中的配置 负载分担配置验证 路由备份&#xff08;浮动静态路由&#xff09;配置验证 缺省路由配置验证 总结 华为HCIA 基础实验&#xff0d;静态路由 & eNSP静态路由 基础…

CFResNet鸟类识别:原网络基础上改进算法

​本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊​ 先放一张ResNet50模型的鸟类识别结果图 一 ResNetSE-NetBN import matplotlib.pyplot as plt import tensorflow as tf import warnings as w w.filterwarnings(ignore) # 支持中文 plt.rcP…

Ubuntu 20.04 出现问号图标且无法联网 修复

在 Ubuntu 中遇到网络连接问题&#xff08;如出现问号图标且无法联网&#xff09;&#xff0c;可以通过以下命令尝试重启网络服务&#xff1a; 1. 推荐先修改DNS 编辑 -> 虚拟机网络编辑器-> VMnet8 ->NAT 设置 -> DNS 设置 -> 设置DNS 服务器 DNS填什么 取决…

基于Contiue来阅读open-r1中的GRPO训练代码

原创 快乐王子HP 快乐王子AI说 2025年04月03日 23:54 广东 前面安装了vscode[1]同时也安装了Coninue的相关插件[2]&#xff0c;现在想用它们来阅读一下open-r1项目的代码[3]。 首先&#xff0c;从启动训练开始(以GRPO为例子&#xff09; 第一步&#xff0c;使用TRL的vLLM后端…

51c嵌入式~单片机~合集7~※

我自己的原文哦~ https://blog.51cto.com/whaosoft/13692314 一、芯片工作的心脏--晶振 在振荡器中采用一个特殊的元件——石英晶体&#xff0c;它可以产生频率高度稳定的交流信号&#xff0c;这种采用石英晶体的振荡器称为晶体振荡器&#xff0c;简称晶振。 制作方法 …

英菲克(INPHIC)A9无线蓝牙鼠标 链接电脑的方式

英菲克&#xff08;INPHIC&#xff09;A9鼠标链接至电脑时&#xff0c;要长按住“模式切换MODE”按钮5秒左右的时间&#xff0c;此时模式指示灯变成蓝色&#xff0c;并且闪烁。 这时使用电脑的蓝牙设置中&#xff0c;“添加设备”&#xff0c;会出现BT4.0 Mouse提示&#xff0…

lua表table和JSON字符串互转

--print("local ssxc{\n"..string.gsub(str,":","").."\n}") Utils {} ---------------------------------------------------------------------------------- -- Lua-Table 与 string 转换 local function value2string(value, isA…

【每日一个知识点】分布式数据湖与实时计算

在现代数据架构中&#xff0c;分布式数据湖&#xff08;Distributed Data Lake&#xff09; 结合 实时计算&#xff08;Real-time Computing&#xff09; 已成为大数据处理的核心模式。数据湖用于存储海量的结构化和非结构化数据&#xff0c;而实时计算则确保数据能够被迅速处理…

c语言数据结构--------拓扑排序和逆拓扑排序(Kahn算法和DFS算法实现)

#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h>//使用卡恩算法(Kahn)和深度优先算法(DFS)实现//拓扑排序和逆拓扑排序//拓扑排序和逆拓扑排序顶点顺序相反//图&#xff0c;邻接矩阵存储 #define MaxVertexNum 100 …

谷粒微服务高级篇学习笔记整理---nginx搭建正反向代理

正向与反向代理 **正向代理:**客户端向代理服务器发请求并指定目标服务器,代理向目标转交请求并将获得的内容转给客户端。 反向代理:用户直接访问反向代理服务器就可以获得目标服务器的资源。反向代理服务器统一了访问入口。 给首页配置反向代理 修改windows的hosts文件配…

2.pycharm保姆级安装教程

一、pycharm安装 1.官网上下载好好软&#xff0c;双击打开 2.下一步 3.修改路径地址 (默认也可以) 4.打勾 5.安装 不用重启电脑 二、添加解释器 1.双击软件&#xff0c;打开 2.projects – new project 3.指定项目名字&#xff0c;项目保存地址&#xff0c;解释器 4.右击 – …

【SQL】取消sql某一列的唯一值key值的方法

在插入数据到sql时&#xff0c;遇到了这个问题&#xff1a; Duplicate entry ‘XXX’ for key 起因是&#xff1a; 我之前设计表的时候&#xff0c;手动给product_title 这个列加了一个key&#xff0c; key 是这个字段的唯一键约束&#xff0c;就不能重复在这一列存入重复的数…

数据库--SQL

SQL&#xff1a;Structured Query Language&#xff0c;结构化查询语言 SQL是用于管理关系型数据库并对其中的数据进行一系列操作&#xff08;包括数据插入、查询、修改删除&#xff09;的一种语言 分类&#xff1a;数据定义语言DDL、数据操纵语言DML、数据控制语言DCL、事务处…

SQL语句(一)—— DDL

目录 一、SQL 基础知识 &#xff08;一&#xff09;SQL 通用语法 &#xff08;二&#xff09;SQL 分类 二、DDL —— 数据库操作 1、查询所有数据库 2、查询当前数据库 3、创建数据库 4、删除数据库 5、切换数据库 三、DDL —— 表操作 &#xff08;一&#xff09;查…

Husky目标跟踪

1.0设备清单 幻影峡谷、适配器 摄像头及数据线、显卡欺骗器 外接屏幕、键盘鼠标 Husky底盘、便携显示屏、键盘鼠标 移动电源 1.1连线 插排——移动电源幻影峡谷——适配器——插排摄像头——幻影峡谷&#xff08;摄像头固定在机械臂前方的底盘上&#xff09;键盘鼠标显示器…

Python----机器学习(线性回归:自求导的方法实现)

一、线性回归方程 目标&#xff1a; 线性回归的目标是找到最佳的系数来使模型与观察到的数据尽可能拟合。 应用&#xff1a; 预测&#xff1a;给定自变量的值&#xff0c;预测因变量的值。 回归分析&#xff1a;确定自变量对因变量的影响程度 线性回归是统计学和机器学习中最简…

Springcache+xxljob实现定时刷新缓存

目录 SpringCache详解 SpringCache概述 核心原理 接口抽象与多态 AOP动态代理 核心注解以及使用 公共属性 cacheNames KeyGenerator&#xff1a;key生成器 key condition&#xff1a;缓存的条件&#xff0c;对入参进行判断 注解 xxl-job详解 SpringcacheRedis实现…