277|1

7193

帖子

11

TA的资源

版主

楼主
 

《Hello算法》5、链表的节点删除 [复制链接]

 

《Hello算法》5、创建链表

《Hello算法》5、链表插入

在前面我学习了链表的创建与插入。下面继续学习链表节点的删除。

链表的删除,有几种情况:

1、本身链表为空,那就直接返回。

2、链表只有一个节点,那就直接把链表的内存释放,然后把链表指向NULL。

3、如果要删除的链表是首节点,那么把链表指下一个节点。

4、如果是尾节点,那么就把减一个节点的指针指向空,然后释放尾节点。

5、如果是中间的节点,那就把后一节点的next指向下一个节点的head。

首先创建三个节点,来测试:

  • #include <stdio.h>
  • #include <stdlib.h>
  • //写一个创建节点的函数
  • struct node {
  • int data;
  • struct node *next;
  • };
  • struct node *create_node(int data) {
  • struct node *p = (struct node *)malloc(sizeof(struct node));
  • p->data = data;
  • p->next = NULL;
  • return p;
  • }
  • //写一个插入节点的函数
  • struct node *insert_node(struct node *head, int data) {
  • struct node *p = create_node(data);
  • p->next = head;
  • return p;
  • }
  • //写一个遍历节点的函数
  • void traverse_node(struct node *head) {
  • struct node *p = head;
  • while (p != NULL) {
  • printf("%d \r\n", p->data);
  • p = p->next;
  • }
  • printf("打印结束\n");
  • }
  • //写一个释放所有节点的函数
  • void free_node(struct node *head) {
  • struct node *p = head;
  • while (p != NULL) {
  • struct node *tmp = p;
  • p = p->next;
  • free(tmp);
  • }
  • printf("释放链表结束\n");
  • }
  • int main() {
  • //创建一个链表
  • struct node *head = create_node(1);
  • head = insert_node(head, 2);
  • //插入1个节点
  • head = insert_node(head, 3);
  • //打印链表
  • traverse_node(head);
  • free_node(head);
  • return 0;
  • }

编译后运行:

  • liujianhua@liujianhuadeMac-mini HelloC % gcc node_test.c
  • liujianhua@liujianhuadeMac-mini HelloC % ./a.out
  • 3
  • 2
  • 1
  • 打印结束
  • 释放链表结束
  • liujianhua@liujianhuadeMac-mini HelloC %

在书中给他的示例为:

  • /* 删除链表的节点 n0 之后的首个节点 */
  • // 注意:stdio.h 占用了 remove 关键词
  • void removeItem(ListNode *n0) {
  • if (!n0->next)
  • return;
  • // n0 -> P -> n1
  • ListNode *P = n0->next;
  • ListNode *n1 = P->next;
  • n0->next = n1;
  • // 释放内存
  • free(P);
  • }

然后我使用AI生成了删除节点的函数:

  • /**
  • * 删除链表中的一个节点
  • *
  • * @param head 链表的头节点指针
  • * @param data 要删除的节点的数据值
  • * [url=home.php?mod=space&uid=784970]@return[/url] 返回删除节点后的链表头节点指针
  • *
  • * 此函数遍历链表,寻找数据值匹配的节点,并将其从链表中删除
  • * 如果找到了匹配的节点,将其释放并返回删除节点后的链表头节点指针
  • * 如果没有找到匹配的节点,则返回原始的链表头节点指针
  • */
  • struct node *delete_node(struct node *head, int data) {
  • // 初始化指针p,用于遍历链表
  • struct node *p = head;
  • // 遍历链表,直到指针p为NULL
  • while (p != NULL) {
  • // 检查当前节点的数据值是否与要删除的值匹配
  • if (p->data == data) {
  • // 如果匹配,保存当前节点的指针到tmp
  • struct node *tmp = p;
  • // 指针p指向下一个节点
  • p = p->next;
  • // 释放匹配节点的内存
  • free(tmp);
  • // 返回链表的头节点指针
  • return head;
  • }
  • // 如果当前节点数据值不匹配,则移动到下一个节点
  • p = p->next;
  • }
  • // 如果没有找到匹配的节点,返回原始的头节点指针
  • return head;
  • }

为了测试效果,我编写主程序如下:

  • int main() {
  • //创建一个链表
  • struct node *head = create_node(1);
  • head = insert_node(head, 2);
  • //插入1个节点
  • head = insert_node(head, 3);
  • //打印链表
  • traverse_node(head);
  • head = delete_node(head, 2);
  • traverse_node(head);
  • free_node(head);
  • return 0;
  • }

测试效果:

  • liujianhua@liujianhuadeMac-mini HelloC % gcc node_test.c
  • liujianhua@liujianhuadeMac-mini HelloC % ./a.out
  • 3
  • 2
  • 1
  • 打印结束
  • 数据为:2 删除成功
  • 3
  • 684081200

但是好象出错了:

重写:

  • // 写一个删除节点的函数
  • struct node *delete_node(struct node *head, int data) {
  • // 如果要删除的是头节点
  • if (head != NULL && head->data == data) {
  • struct node *tmp = head;
  • head = head->next;
  • free(tmp);
  • return head;
  • }
  • // 遍历链表寻找要删除的节点
  • struct node *current = head;
  • while (current != NULL && current->next != NULL) {
  • if (current->next->data == data) {
  • struct node *tmp = current->next;
  • current->next = current->next->next;
  • free(tmp);
  • return head;
  • }
  • current = current->next;
  • }
  • // 如果没有找到要删除的节点,返回原始头节点
  • return head;
  • }

测试:

  • liujianhua@liujianhuadeMac-mini HelloC % ./a.out
  • 3
  • 2
  • 1
  • 打印结束
  • 3
  • 2
  • 打印结束
  • 释放链表结束

【总结】

删除链表的节点,需要考虑许多特殊的情况。但是相比数组,删除链表的速度要快一些。

还有就是在插入链表时,需要考虑是尾插还是前插。

查看本帖全部内容,请登录或者注册

最新回复

要删除的链表是首节点,那么把链表指下一个节点,有这种情况   详情 回复 发表于 2025-2-3 10:08
点赞 关注(1)
 
 

回复
举报

6972

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

要删除的链表是首节点,那么把链表指下一个节点,有这种情况

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
立即报名 | 2025 瑞萨电子工业以太网技术日即将开启!
3月-4月 深圳、广州、北京、苏州、西安、上海 走进全国6城
2025瑞萨电子工业以太网技术巡回沙龙聚焦工业4.0核心需求,为工程师与企业决策者提供实时通信技术最佳解决方案。
预报从速,好礼等您拿~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表