P6 链表 插入数据节点 尾插法指定节点插入

news2024/12/22 20:23:50

目录

前言                                                  ​编辑               

01  链表指定节点后插入数据(根据节点号插入)

 测试代码

02 链表指定节点后插入数据(根据节点的数据插入)

尾插法的代码 


前言  
                           
                                    

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++》✨✨✨ 

🔥 推荐专栏2: 《 Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

📝推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🍉本篇简介  :  链表数据插入之尾插法

✨ 只有我努力了 才有机会接触成功✨

链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

作为有强大功能的链表,对他的操作当然有许多,比如:

  1. 链表的创建
  2. 链表的链表的遍历打印数据
  3. 链表里面的结构体数据的修改
  4. 链表节点的删除
  5. 链表插入新节点
  6. 链表的数据排序
  7. 链表的反序
  8. 清空链表的元素
  9. 求链表的长度等


在前面几章,我们学习了

  1. 链表的创建
  2. 链表的链表的遍历打印数据
  3. 链表里面的结构体数据的修改
  4. 求链表的长度等
  5. 还有链表结尾插入数据节点,非指定节点

01  链表指定节点后插入数据(根据节点号插入)

我们要在指定的节点后插入数据,提醒一下,这里的节点是指的第几个节点,不是按数值来查

我们定义个函数tailInsertNodeLinkList(),函数的返回值尾int,因为我们需要返回标志位

用于查看是否错误

这个函数有三个参数,

参数1位一个结构体的指针,因为要传如头节点,

参数2为一个整形数,用于找到第几个节点

参数3为一个整形数,为节点的数据

根据需求,我们可以知道函数体的大致模样了

int tailInsertNodeLinkList(struct Link * head,const int size,const int data)
{
 
}

 然后我们根据需求将代码补全

我们看代码进行分析一下

第109行,定义一个结构体指针,指向了链表头,原因是,操作链表的时候最好不要直接操作链表

第110行,定义了一个整形变量cnt,用于遍历时记录目前是第几节点

第110 - 113行就是定义了一个新节点,并初始化

第114 - 124行就是链表的遍历了

第116行,if语句进行判断,如果当前节点 = 目标节点,就进入if语句

里面到底做了什么事呢?

大致就是这样,先让新的节点的next = prev的next,

在将prev的next指向new

就是这样,很简单

我们代码测试一下

 

链表开始的时候只有头节点,我们先用上一章的函数,尾插法增长了链表,我这里输入了8和5

那按道理链表现在又了三个数1 8 2

现在我要用 这一章的代码在第二个节点插入数据5

所以最后打印的时候是1 8 5 2

没有问题

 测试代码

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

struct Link
{
    int data;
    struct Link *next;
};

/*打印链表数据*/
void PrintLink(struct Link *head)
{
    struct Link *prev = head;
    while (NULL != prev) 
    {
        printf("%d  ", prev->data);
        prev = prev->next;
    }
    printf("\n");
}


/*尾部顺序插入形成链表*/
int tailInsertLinkList(struct Link * head,int data)
{
    if(NULL == head) 
    {
        return -1;
    }
    struct Link *prev = head;
    struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
    new->data = data;
    new->next = NULL;
    while (NULL != prev)
    {
        if(NULL == prev->next)
        {
            prev->next = new;
            return 1;
        }
        prev = prev->next;
    }
    return -1;
}

int tailInsertLinkListPro(struct Link * head,const int size)
{
    int *bufData = (int*)malloc(sizeof(int)*size);
    for(int i = 0; i < size; i++)
    {
        scanf("%d", bufData+i);
        tailInsertLinkList(head,bufData[i]);
    }
}

/*参数1 结构体指针头节点的地址,参数2第几个节点后插入数据,参数3要插入的数据*/
int tailInsertNodeLinkList(struct Link * head,const int size,const int data)
{
    struct Link *prev = head;
    int cnt = 1;
    struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
    new->next = NULL;
    new->data = data;
    while (NULL != prev)
    {
        if(cnt == size)
        {
            new->next = prev->next;
            prev->next = new;
            return 1;
        }
        cnt++;
        prev = prev->next;
    }
    return -1;
}

int main()
{
    struct Link head = {1,NULL};
    int size = 0;
    puts("请输入你要在链表尾部插入的数据数目");
    scanf("%d",&size);
    printf("请按要求输入%d个数据\n",size);
    tailInsertLinkListPro(&head,size);
    tailInsertNodeLinkList(&head,2,5);
    PrintLink(&head);
    return 0;
}

02 链表指定节点后插入数据(根据节点的数据插入)

刚写完根据目标节点数进行节点插入,现在我们写一个根据节点的数据进行插入,如果于于目标数据一致,则在其后插入一个新节点

如果成功返回目标目前节点号

失败返回-1

这个代码其实也很简单,和前面的长的差不多,就是找的目标数据后,进行新节点插入

int tailDtaNodeLinkList(struct Link *head,const int targetData,const int data)
{
    struct Link *prev = head;
    struct Link *new = (struct Link*)malloc(sizeof(struct Link));
    new->data = data;
    new->next = NULL;
    int cnt = 1;
    while (prev!= NULL)
    {
        if(prev->data == targetData)
        {
            new->next = prev->next;
            prev->next = new;
            return cnt;
        }
        cnt++;
        prev = prev->next;
    }
    puts("数据插入失败");
    return -1;
}

函数的参数1为头节点的地址,参数2为目标节点的数据,参数3为新节点的数据 

尾插法的代码 

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

struct Link
{
    int data;
    struct Link *next;
};

/*打印链表数据*/
void PrintLink(struct Link *head)
{
    struct Link *prev = head;
    while (NULL != prev) 
    {
        printf("%d  ", prev->data);
        prev = prev->next;
    }
    printf("\n");
}

/*获取链表的节点数*/
int GetLinkNum(struct Link *head)
{
    struct Link *prev = head;
    int count = 0;
    while (prev != NULL)
    {
        count++;
        prev = prev->next;
    }
    return count;
}

/* 查找链表中的数据,只能找到一个,且不知道节点数*/
int findLinkData(struct Link *head,int data)
{
    struct Link *prev = head;
    while (prev!= NULL)
    {
        if (prev->data == data)
        {
            return 1;
        }
        prev = prev->next;
    }
    return 0;
}

/* 在链表中查找需要的数据,如果有,打印节点号和数据*/
void FindLinkDataPro(struct Link *head,int data)
{
   int count = 0;     //遍历记录节点号
   int NumFd =0;   // Number数据的索引
   int Number[32] = {0};
   struct Link *prev = head;
   while (prev!= NULL)
   {
        if(prev->data == data)
        {
            Number[NumFd++] = count;
        }
        count++; 
        prev = prev->next;
   }
    for(int i = 0; i < NumFd; i++)
    {
        printf("节点号:%d  查找的数据%d\n",Number[i]+1,data);
    }
}

/*尾部顺序插入形成链表*/
int tailInsertLinkList(struct Link * head,int data)
{
    if(NULL == head) 
    {
        return -1;
    }
    struct Link *prev = head;
    struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
    new->data = data;
    new->next = NULL;
    while (NULL != prev)
    {
        if(NULL == prev->next)
        {
            prev->next = new;
            return 1;
        }
        prev = prev->next;
    }
    return -1;
}

int tailInsertLinkListPro(struct Link * head,const int size)
{
    int *bufData = (int*)malloc(sizeof(int)*size);
    for(int i = 0; i < size; i++)
    {
        scanf("%d", bufData+i);
        tailInsertLinkList(head,bufData[i]);
    }
}

/*参数1 结构体指针头节点的地址,参数2第几个节点后插入数据,参数3要插入的数据*/
int tailInsertNodeLinkList(struct Link * head,const int size,const int data)
{
    struct Link *prev = head;
    int cnt = 1;
    struct Link *new = (struct Link*)malloc(sizeof(struct Link ));
    new->next = NULL;
    new->data = data;
    while (NULL != prev)
    {
        if(cnt == size)
        {
            new->next = prev->next;
            prev->next = new;
            return 1;
        }
        cnt++;
        prev = prev->next;
    }
    return -1;
}

int tailDtaNodeLinkList(struct Link *head,const int targetData,const int data)
{
    struct Link *prev = head;
    struct Link *new = (struct Link*)malloc(sizeof(struct Link));
    new->data = data;
    new->next = NULL;
    int cnt = 1;
    while (prev!= NULL)
    {
        if(prev->data == targetData)
        {
            new->next = prev->next;
            prev->next = new;
            return cnt;
        }
        cnt++;
        prev = prev->next;
    }
    puts("数据插入失败");
    return -1;
}

int main()
{
    struct Link head = {1,NULL};
    int size = 0;
    puts("请输入你要在链表尾部插入的数据数目");
    scanf("%d",&size);
    printf("请按要求输入%d个数据\n",size);
    tailInsertLinkListPro(&head,size);
    tailDtaNodeLinkList(&head,2,5);
    PrintLink(&head);
    return 0;
}

 好了,尾插法就先讲到这里了,如果有什么不太理解或者我写错的,欢迎来一起讨论 

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

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

相关文章

for循环定义域问题

记录一个偶然发现的问题&#xff0c;代码如下 int main(int argc, char *argv[], char *envp[]){for(int i 1; i < 10; i);printf("%d",i); return 0; } 可以看到for循环后加了一个分号&#xff0c;按理说应该报变量i未定义的错误&#xff0c;但此时在编译器中…

RCE绕过

1.[SCTF 2021]rceme 总结下获取disabled_funciton的方式 1.phpinfo() 2.var_dump(ini_get(“disable_functions”)); 3.var_dump(get_cfg_var(“disable_functions”)); 其他的 var_dump(get_cfg_var(“open_basedir”)); var_dump(ini_get_all()); <?php if(isset($_POS…

使用coco数据集进行语义分割(1):数据预处理,制作ground truth

如何coco数据集进行目标检测的介绍已经有很多了&#xff0c;但是关于语义分割几乎没有。本文旨在说明如何处理 stuff_train2017.json stuff_val2017.json panoptic_train2017.json panoptic_val2017.json&#xff0c;将上面那些json中的dict转化为图片的label mask&am…

C++入门篇第十篇----继承

前言&#xff1a; 本篇我们将开始讲解C的继承&#xff0c;我想要说的是&#xff0c;C的主体基本就是围绕类和对象展开的&#xff0c;继承也是以类和对象为主体&#xff0c;可以说&#xff0c;C相较于C优化的地方就在于它对于结构体的使用方法的高度扩展和适用于更多实际的场景…

ffmpeg 任意文件读取漏洞/SSRF漏洞 (CVE-2016-1897/CVE-2016-1898)

漏洞描述 影响范围 FFmpeg 2.8.x < 2.8.5FFmpeg 2.7.x < 2.7.5FFmpeg 2.6.x < 2.6.7FFmpeg 2.5.x < 2.5.10 漏洞环境及利用 搭建docker环境 访问8080端口看到上传界面 由于vulhub并没有讲述该漏洞如何复现&#xff0c;我们需要进入环境查看源码 <?php if(!…

电大搜题:开启你的学习新篇章

广西开放大学&#xff0c;作为一所具有悠久历史和丰富经验的广播电视大学&#xff0c;在教育领域享有盛誉。如今&#xff0c;随着科技的迅猛发展&#xff0c;广西开放大学推出了电大搜题微信公众号&#xff0c;为广大学子提供了一个便捷、高效的学习工具。 电大搜题微信公众号…

2_企业级Nginx使用-day1

#企业级Nginx使用-day1 学习目标和内容 1、能够了解Nginx的信号参数 2、能够进行平滑升级Nginx 3、能够配置server虚拟机 4、能够部署上线项目到LNMP架构中 5、能够了解Nginx的常用官方模块 6、能够了解日志相关使用 一、重装和升级 在实际业务场景中&#xff0c;需要使用软件…

linux之buildroot(2)配置toolchain

Linux之buildroot(2)配置toolchain Author&#xff1a;Onceday Date&#xff1a;2023年11月27日 漫漫长路&#xff0c;才刚刚开始… 全系列文章请查看专栏: buildroot编译框架_Once_day的博客-CSDN博客 参考文档&#xff1a; Buildroot - Making Embedded Linux Easy 文章…

.net7.0中把exe和dll分开打包

之前写过 C#把dll分别放在指定的文件夹_wpf core dll 放文件夹-CSDN博客 C#把dll打包到exe_c# 打包exe_故里2130的博客-CSDN博客 这都是老技术了&#xff0c;可以进行参考。 现在的.netcore系列有单独支持把exe和dll分开打包的功能了&#xff0c;当然也支持.net7.0和.net8.…

吉他初学者学习网站搭建系列(4)——如何查询和弦图

文章目录 背景实现ChordDbvexchords 背景 作为吉他初学者&#xff0c;如何根据和弦名快速查到和弦图是一个必不可少的功能。以往也许你会去翻和弦的书籍查询&#xff0c;像查新华字典那样&#xff0c;但是有了互联网后我们不必那样&#xff0c;只需要在网页上输入和弦名&#…

在国外,职业生命期长,是因为敬业吗?

不知道有没有朋友关注围棋比赛&#xff1f;昨天进行了农心杯三国围棋擂台赛第二轮的攻擂战&#xff0c;结果中国棋手谢尔豪半目险胜韩国棋手元晟臻。 棋局本身很精彩&#xff0c;更引人注目的是韩国棋手已经是 38 岁高龄。所以有网友发出感叹&#xff0c;中国的领军人物玩直播、…

Xilinx FPGA平台DDR3设计详解(三):DDR3 介绍

本文介绍一下常用的存储芯片DDR3&#xff0c;包括DDR3的芯片型号识别、DDR3芯片命名、DDR3的基本结构等知识&#xff0c;为后续掌握FPGA DDR3的读写控制打下坚实基础。 一、DDR3芯片型​号 电路板上的镁光DDR3芯片上没有具体的型号名。 ​如果想知道具体的DDR3芯片型号&#…

Python中用于机器学习的Lazy Predict库

Python是一种多功能语言&#xff0c;你可以用它来做任何事情。Python的一个伟大之处在于&#xff0c;有这么多的库使它变得更加强大。Lazy Predict就是其中一个库。它是机器学习和数据科学的一个很好的工具。在本文中&#xff0c;我们将了解它是什么&#xff0c;它做什么&#…

k8s中Service负载均衡和Service类型介绍

目录 一.service介绍 二.service参数详解 三.定义service的两种方式 1.命令行expose 2.yaml文件 四.service负载均衡配置 1.kube-proxy代理模式 &#xff08;1&#xff09;设置ipvs &#xff08;2&#xff09;负载均衡调度策略 2.会话保持 3.案例演示 五.四种Servi…

51单片机 -全球【最笨】学习法

全球属我最笨 1> 还有比我笨的吗&#xff1f;2> 4个回合&#xff01;拿下51单片机第1回合> 先学各个外围驱动模块第2回合> 自己写各个外围模块程序第3回合> 学习开源实战小项目第4回合> 小项目-视频讲解 1> 还有比我笨的吗&#xff1f; 有兄弟&#xff0…

(C语言)逆序输出字符串

#include<stdio.h> #include<string.h> int main() {int i;char s[100];scanf("%s",&s);int count strlen(s);for(int i count -1;i > 0; i --)printf("%c",s[i]);return 0;} 代码运行截图&#xff1a; 注&#xff1a;侵权可删

号称要做人民货币的Spacemesh,有何新兴叙事?

​打开Spacemesh的官网&#xff0c;率先映入眼帘的是一个响亮的口号——On a quest to become the people’s coin&#xff08;致力于成为人民的货币&#xff09;&#xff01;Spacemesh 联合创始人 Tomer Afek 曾表示“Spacemesh 的低准入门槛和激励兼容性&#xff0c;激发了从…

Hdoop学习笔记(HDP)-Part.12 安装HDFS

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

二叉树遍历及应用

文章目录 前言构建二叉树前序遍历中序遍历后序遍历二叉树的结点个数二叉树的叶节点个数二叉树的高度二叉树第K层结点个数 前言 二叉树的遍历及应用主要是运用了递归、分治的思想。在这一篇文章&#xff0c;小编将介绍二叉树的前序遍历、中序遍历、后序遍历&#xff0c;求二叉树…

微软Copilot魔法来袭!用自然语言,点燃你的工作热情

近日我们发布了全新Copilot功能&#xff0c;旨在通过智能化的工作方式&#xff0c;提高企业整体的生产力和客户体验。新一代的Copilot结合了先进的AI技术&#xff0c;通过自然语言交互&#xff0c;为用户提供即时、个性化的信息和解决方案。这一变革性的工具将为现场服务人员提…