当前位置: 首页 > news >正文

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

一:为什么要删除节点

        (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释放或程序终止

相关文章:

  • nginx的匹配及重定向
  • linux配置qqbot(Mirai+Alicebot)
  • 企业搭建知识库:解锁无限潜力的钥匙
  • Hadoop页面报错Permission denied: user=dr.who, access....
  • 详细分析Spring Boot 数据源配置的基本知识(附配置)
  • [C++初阶]vector的初步理解
  • 7.1作业6
  • vector与list的简单介绍
  • 收银系统源码-营销活动-幸运抽奖
  • SpringMVC(1)——入门程序+流程分析
  • MAX98357、MAX98357A、MAX98357B小巧、低成本、PCM D类IIS放大器,具有AB类性能中文说明规格书
  • 使用任意电脑通过内网穿透生成的公网地址远程SSH连接本地Windows电脑
  • docker-compose搭建minio对象存储服务器
  • c++ primer plus 第15章友,异常和其他:15.1.2 友元成员函数
  • HTML+CSS笔记
  • 【剑指offer】让抽象问题具体化
  • ES6简单总结(搭配简单的讲解和小案例)
  • in typeof instanceof ===这些运算符有什么作用
  • input的行数自动增减
  • k个最大的数及变种小结
  • Less 日常用法
  • Mac转Windows的拯救指南
  • mysql 5.6 原生Online DDL解析
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • windows下如何用phpstorm同步测试服务器
  • Xmanager 远程桌面 CentOS 7
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 将 Measurements 和 Units 应用到物理学
  • 前端面试题总结
  • 嵌入式文件系统
  • 思维导图—你不知道的JavaScript中卷
  • 突破自己的技术思维
  • 新版博客前端前瞻
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​MySQL主从复制一致性检测
  • #if 1...#endif
  • (12)Linux 常见的三种进程状态
  • (20050108)又读《平凡的世界》
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (六)c52学习之旅-独立按键
  • (七)glDrawArry绘制
  • (算法)Travel Information Center
  • (五)c52学习之旅-静态数码管
  • .Net CoreRabbitMQ消息存储可靠机制
  • .net core控制台应用程序初识
  • .Net8 Blazor 尝鲜
  • .Net的DataSet直接与SQL2005交互
  • .NET建议使用的大小写命名原则
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [AIGC] 解题神器:Python中常用的高级数据结构
  • [Angular] 笔记 7:模块
  • [C# WPF] 如何给控件添加边框(Border)?