C语言单链表的算法之删除节点

news2024/11/26 20:24:20

一:为什么要删除节点

        (1)有时候链表中节点的数据不想要了,就要删除这个节点

二:删除节点的两个步骤

        (1)第一步:找到这个节点

        (2)第二步:删除这个节点

三:如何找到待删除的节点

        (1)通过遍历来查找节点1.从头指针+头节点开始,顺着链表依次将各个节点拿出来,按照一定的方法对比,找到要删除的那个节点

四:如何删除一个节点

        1:待删除的节点不是尾节点的情况

                (1)第一步:把待删除的节点的前一个节点的pnext指针指向待删除节点的下一个节点的首地址(这样就把要删除的那个节点从链表中摘出来了)

                (2)第二步:把这个摘出来的节点free掉

                

        2:待删除的节点是尾节点的情况

                (1)第一步:把待删除的尾节点前一个节点的pnext指针指向null(相当于原来尾节点的前一个节点变成了尾节点)

                (2)第二步将之前的尾节点free掉

函数实现代码:

/*****************************************
函数名:delete
返回值:0 或 -1 返回0表示删除成功 -1 表示删除失败
参数:ph:单链表的头指针 data:需要删除的节点的数据区存放的数据(通过数据找到对应的节点来删除这个节点)
作用:通过头指针访问单链表,对链表的各个节点进行遍历,当找到某个节点的有效数据区的数据是指定的那个时,删除那个对应的节点
*****************************************/
int delete(struct node *ph,int data)    
{

    struct node *p = ph;        //定义一个临时指针变量,将它执行头指针

    struct node *prev = NULL;   //再定义一个临时指针变量用来存放要删除的节点的上一个节点
                                //的位置,因为进行遍历时指针已经指向后面返回不了前面
                                //而要为了实现只是删除某个节点,并且保证链表还是能正常
                                //访问,需要要删除的前一个节点的pnext执行要删除的节点
                                //的后一个节点的首地址,所以需要留有要删除的节点的前一个
                                //节点的位置  

    int cat = 0;                //用来修改节点计数区

    while(NULL !=  p->pNEXT)    //判断是否指针NULL    
            {
                prev = p;       
                p = p->pNEXT;   
                if(p->datas == data)  //判断当前节点是不是要删除的那个节点
                    {

                        //进入即说明这个节点是要删除的节点

                        if(NULL == p->pNEXT)    //再次进行判断这个节点是不是尾节点
                            {       
                
                                prev->pNEXT  = NULL;   //是尾节点就将要删除的前一个节点
                                                       //指向NULL让前一个节点变成尾部
                                free(p);               //删除节点 
                                cat = ph->datas;       //临时变量读取头指针数据区存放的
                                                       //节点数
                                ph->datas = cat -1;    //将之前头指针存放的数据进行-1
                                                       //再赋值给头指针的有效数据区
                            }
                        else
                            {
                                prev->pNEXT  = p->pNEXT;
                                free(p);
                                cat = ph->datas;
                                ph->datas = cat -1;

                            }   

                            return 0;

                    }    



                
                 
     
                




            }

            return -1;


}

完整程序代码:

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

struct node
{

    int datas;
    struct node *pNEXT;


};

struct node *create(int a)
{


    struct node *p = (struct node *)malloc(sizeof(struct node));

    if(NULL == p)
        {
            printf("malloc error!\n");

            return NULL;

        }

      memset(p,0,sizeof(struct node));  
      //bzero(p,sizeof(struct node));

      p->datas = a;
      p->pNEXT = NULL;


      return p;


}



void insert_tail(struct node *phead,struct node *new)
{

    struct node *p = phead;
    int cat = 0;
    while(NULL !=  p->pNEXT)
        {


            p = p->pNEXT;
            cat++;

        }

        p->pNEXT = new;
        phead->datas = cat +1;


}



void insert_head(struct node *head,struct node *new)
{

    new->pNEXT =  head->pNEXT;

    head->pNEXT = new;

    head->datas += 1;

}

void ergodic(struct node *ph)
{


        struct node *p = ph;
        int cat = 0;

        printf("datas number is a: %d\n",p->datas);

        while(NULL !=  p->pNEXT)
            {
                cat++;
                printf("datas number is :%d\n",cat);  
                p = p->pNEXT;  
                printf("datas is: %d\n",p->datas);    
                




            }

        


}


int delete(struct node *ph,int data)
{

    struct node *p = ph;
    struct node *prev = NULL;
    int cat = 0;
    while(NULL !=  p->pNEXT)
            {
                prev = p;
                p = p->pNEXT; 
                if(p->datas == data)
                    {

                        if(NULL == p->pNEXT)
                            {       
                
                                prev->pNEXT  = NULL;
                                free(p);
                                cat = ph->datas;
                                ph->datas = cat -1;
                            }
                        else
                            {
                                prev->pNEXT  = p->pNEXT;
                                free(p);
                                cat = ph->datas;
                                ph->datas = cat -1;

                            }   

                            return 0;

                    }    



                
                 
     
                




            }

            return -1;


}



int main(void)
{
    struct node *phead = create(0);

    insert_tail(phead,create(12));   
    insert_tail(phead,create(13));
    insert_tail(phead,create(14));

    ergodic(phead);     //遍历打印各个节点数据区

    delete(phead,13);   //删除数据区为13的节点

   

        ergodic(phead);    //再次遍历打印各个节点数据区

        
      return 0;


}

运行结果:

 

五:注意堆内存的释放

        (1)当程序运行结束时堆内存就会被释放,在结束之前没有free释放掉的堆内存也会被释放掉

        (2)有时候程序运行时间久,这时候malloc的内存没有free会一直被占用直到free释放或程序终止

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

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

相关文章

麒麟桌面系统CVE-2024-1086漏洞修复

原文链接&#xff1a;麒麟桌面操作系统上CVE-2024-1086漏洞修复 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇在麒麟桌面操作系统上修复CVE-2024-1086漏洞的文章。漏洞CVE-2024-1086是一个新的安全漏洞&#xff0c;如果不及时修复&#xff0c;可能会对系统造成安全…

Rust单元测试、集成测试

单元测试、集成测试 在了解了如何在 Rust 中写测试用例后&#xff0c;本章节我们将学习如何实现单元测试、集成测试&#xff0c;其实它们用到的技术还是上一章节中的测试技术&#xff0c;只不过对如何组织测试代码提出了新的要求。 单元测试 单元测试目标是测试某一个代码单…

算法金 | K-均值、层次、DBSCAN聚类方法解析

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 聚类分析概述 聚类分析的定义与意义 聚类分析&#xff08;Clustering Analysis&#xff09;是一种将数据对象分成多个簇&#xff08;…

AI 音乐生成器 MusicGPT,同声传译StreamSpeech!Web短视频平台Sharine

AI 音乐生成器 MusicGPT&#xff0c;同声传译StreamSpeech!Web短视频平台Sharine。 项目简介 MusicGPT 是一款应用程序&#xff0c;允许在任何平台上以高性能方式本地运行最新的音乐生成 AI 模型&#xff0c;而无需安装 Python 或机器学习框架等严重依赖项。 目前它仅支持 Me…

【python】OpenCV—Aruco

文章目录 Detect ArucoGuess Aruco Type Detect Aruco 学习参考来自&#xff1a;OpenCV基础&#xff08;19&#xff09;使用 OpenCV 和 Python 检测 ArUco 标记 更多使用细节可以参考&#xff1a;【python】OpenCV—Color Correction 源码&#xff1a; 链接&#xff1a;http…

二进制方式部署consul单机版

1.consul的下载 mkdir -p /root/consul/data && cd /root/consul wget https://releases.hashicorp.com/consul/1.18.0/consul_1.18.0_linux_amd64.zip unzip consul_1.18.0_linux_amd64.zip mv consul /usr/local/bin/ 2.配置文件 // 配置文件路径&#xff1a; /roo…

Vue 项目运行时,报错Error: Cannot find module ‘node:path‘

Vue 项目运行时&#xff0c;报错Error: Cannot find module ‘node:path’ internal/modules/cjs/loader.js:883throw err;^Error: Cannot find module node:path Require stack: - D:\nodejs\node_modules\npm\node_modules\node_modules\npm\lib\cli.js - D:\nodejs\node_mo…

240628_昇思学习打卡-Day10-SSD目标检测

240628_昇思学习打卡-Day10-SSD目标检测 今天我们来看SSD&#xff08;Single Shot MultiBox Detector&#xff09;算法&#xff0c;SSD是发布于2016年的一种目标检测算法&#xff0c;使用的是one-stage目标检测网络&#xff0c;意思就是说它只需要一步&#xff0c;就能把目标检…

国内多个库被 rsc 钉上 Go 耻辱柱。。。

大家好&#xff0c;我是煎鱼。 这还是比较突然的&#xff0c;下午正努力打工。国内社区群里突然就闹腾起来了。 仔细一看&#xff0c;原来是 Go 核心团队负责人 rsc&#xff0c;又冷不丁搞大招 &#x1f605;。他直接把国内好几个知名库给直接钉上了 Go 源码库的耻辱柱上了。 如…

普元EOS学习笔记-EOS8.3精简版安装

前言 普元EOS是优秀的高低开结合的企业应用软件开发框架。 普元&#xff1a;这是普元公司的名字&#xff0c;普元信息&#xff0c;上市公司哦&#xff0c;这里就不过多安利了。 EOS&#xff1a;普元公司的企业应用开发系统&#xff0c;开发语言是基于Java&#xff0c;技术框…

JavaScript(2)——输入输出和执行顺序

目录 JS的输入输出语法 输出&#xff1a; 输入 JS的代码执行顺序 字面量 JS的输入输出语法 输出&#xff1a; document.write(内容)alert(内容) 页面弹出警告框console.log(内容) 控制台输出语法&#xff0c;程序员调试使用 作用&#xff1a;向body输出内容 注意&…

zabbix-server的搭建

zabbix-server的搭建 部署 zabbix 服务端(192.168.99.180) rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm cd /etc/yum.repos.d sed -i s#http://repo.zabbix.com#https://mirrors.aliyun.com/zabbix# zabbix.r…

音频分离人声和伴奏可以实现吗?手机人声分离工具10款无偿分享!

随着科技的飞速发展&#xff0c;音频处理技术已经取得了显著的进步&#xff0c;其中音频分离人声和伴奏已成为现实。这一技术不仅为音乐制作人和音频工程师提供了便利&#xff0c;更为广大音乐爱好者提供了无限的创作可能性。本文将为大家分享10款手机人声分离工具&#xff0c;…

前端面试题(基础篇十二)

一、link标签定义、与import的区别 link 标签定义文档与外部资源的关系。 link 元素是空元素&#xff0c;它仅包含属性。 此元素只能存在于 head 部分&#xff0c;不过它可出现任意数。 link 标签中的 rel 属性定义了当前文档与被链接文档之间的关系。常见的 stylesheet 指的是…

C# 警告 warning MSB3884: 无法找到规则集文件“MinimumRecommendedRules.ruleset”

警告 warning MSB3884: 无法找到规则集文件“MinimumRecommendedRules.ruleset” C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Microsoft.CSharp.CurrentVersion.targets(129,9): warning MSB3884: 无法找到规则集文件“MinimumRe…

好书速览-深入理解JVM-Part1

文章目录 第二章、Java内存区域与内存溢出异常2.1 概述2.2 运行时数据区域程序计数器&#xff08;program Counter Register)Java虚拟机栈本地方法栈堆方法区运行时常量池直接内存 2.3 对象生命周期2.3.1 对象的创建2.3.2 对象的内存布局对象头类型指针对齐填充 2.3.3 对象的访…

WordPress免费模板:惊艳动态效果,打造视觉盛宴

WordPress免费模板&#xff1a;惊艳动态效果&#xff0c;打造视觉盛宴 我们为您带来了一款独具特色的WordPress免费模板&#xff0c;这款模板以其独特的动态效果设计&#xff0c;特别是引人注目的动态banner图片效果&#xff0c;为您的网站注入活力&#xff0c;打造一场视觉盛…

某配送平台未授权访问和弱口令(附赠nuclei默认密码验证脚本)

找到一个某src的子站&#xff0c;通过信息收集插件&#xff0c;发现ZABBIX-监控系统&#xff0c;可以日一下 使用谷歌搜索历史漏洞&#xff1a;zabbix漏洞 通过目录扫描扫描到后台&#xff0c;谷歌搜索一下有没有默认弱口令 成功进去了&#xff0c;挖洞就是这么简单 搜索文章还…

定时触发-uniapp + uniCloud 订阅消息实战教程(三)

上一节已经对云函数有了一定的了解,但是,为了发送订阅消息,只会云函数还是差了那么一点意思,所以接下来的这一节,将带领大家熟悉一下定时触发。 熟悉定时触发 如果云函数需要定时/定期执行,即定时触发,您可以使用云函数定时触发器。已配置定时触发器的云函数,会在相应…

SwiftUI八与UIKIT交互

代码下载 SwiftUI可以在苹果全平台上无缝兼容现有的UI框架。例如&#xff0c;可以在SwiftUI视图中嵌入UIKit视图或UIKit视图控制器&#xff0c;反过来在UIKit视图或UIKit视图控制器中也可以嵌入SwiftUI视图。 本文展示如何把landmark应用的主页混合使用UIPageViewController和…