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

单链表删除算法(p=L; j=0;与p=p->next;j=1的辨析)

 

 算法描述

Status ListDelete(LinkList &L,int i)
{
//在带头结点的单链表 L 中,删除第 i 个元素
p=L;  j=0;
while ((p->next) && (j<i-1))  
       {p=p->next;  ++j;}
if (!(p->next)||(j>i-1))  return ERROR;
q=p->next;
p->next=q->next;
delete q;
return OK;   
}

在带头结点的单链表中删除第i个元素时,正确的初始化方式是 p = L; j = 0;。原因如下:


关键逻辑

  1. 头结点不存储数据
    头结点 L 是虚拟节点,真正的数据从 L->next 开始。要删除第 i 个元素,需找到它的前驱节点(即第 i-1 个节点)。

  2. 循环条件的作用
    while (p->next && j < i-1) 的目的是让指针 p 移动到第 i-1 个节点。

    • j 从 0 开始计数,每移动一次 pj 自增,最终 j = i-1 时停止。
    • 如果 p->next 为空,说明链表长度不足,无法删除第 i 个元素。
  3. 为什么 p = L; j = 0 正确?

    • 初始时 p 指向头结点 Lj = 0 表示当前处于第 0 个位置(头结点)。
    • 循环结束后,p 指向第 i-1 个节点,此时 p->next 就是待删除的第 i 个节点。
    • 例子:删除第 1 个元素(i=1)时,循环不执行,p 仍指向头结点 L,直接操作 p->next 即可。

错误写法分析

如果初始化时写 p = p->next; j = 1(假设 p 已指向 L):

  1. 指针 p 直接跳过头结点,指向第一个数据节点,j 初始化为 1
  2. 问题
    • 无法处理 i=1 的情况(需要头结点 L 作为前驱)。
    • 当 i=1 时,j 初始为 1,循环条件 j < 0 不成立,直接判断 p->next,但此时 p 指向第一个数据节点,无法正确删除自身。

总结

  • 正确初始化p = L; j = 0
    从头结点开始遍历,确保能处理所有合法位置(包括 i=1)。
  • 错误写法p = L->next; j = 1
    跳过了头结点,导致无法正确删除第一个元素。

代码正确性验证:

cpp复制代码

p = L;    // p 指向头结点
j = 0;    // 当前处于第 0 个位置
while (p->next && j < i-1) {  // 移动 i-1 次
    p = p->next;
    j++;
}
if (!p->next || j > i-1) return ERROR;  // 位置非法
q = p->next;         // q 指向待删除节点
p->next = q->next;   // 绕过 q
delete q;             // 删除节点

http://www.kler.cn/a/566907.html

相关文章:

  • HBuilder X中,uni-app、js的延时操作及定时器
  • 【网络】网络层IP协议
  • Ubuntu22.04安装docker教程
  • 大白话解释负载均衡Nginx是什么 有什么用 怎么用#
  • 力扣hot100刷题——41~50
  • Linux:理解O(1)调度算法的设计精髓
  • 请谈谈 React 中的状态管理,如何使用 Context API 和 Redux 进行状态管理?
  • BMS应用软件开发 — 13 Modbus协议详解
  • DeepSeek+Origin复现顶刊图表,以《Nature Energy》典型电化学数据可视化为例
  • 《Keras 3 使用 NeRF 进行 3D 体积渲染》:此文为AI自动翻译
  • 【Go语言快速上手】第一部分:函数与错误处理
  • 【现代Web布局与动画技术:卡片组件实战分享】
  • python模拟监测自动驾驶模拟过程中违反交通规则的车辆
  • 【每日八股】MySQL篇(六):存储引擎
  • redis的客户端连接的可视化管理工具
  • Springboot服务接入prometheus 监控
  • 【机试】链表linklist
  • 面试基础---Spring生态---Spring Bean 生命周期
  • MFC线程
  • RabbitMQ系列(六)基本概念之Routing Key