
本文详解单链表按指定索引插入节点的实现逻辑,重点纠正常见错误——误将新节点链接到前驱而非后继,导致插入失效,并提供完整、健壮的insert(i, value)方法实现。
本文详解单链表按指定索引插入节点的实现逻辑,重点纠正常见错误——误将新节点链接到前驱而非后继,导致插入失效,并提供完整、健壮的`insert(i, value)`方法实现。
在单链表中按索引插入节点是一个基础但易错的操作。问题核心在于:必须准确找到插入位置的前驱节点(prev),然后将新节点插入到 prev 和原第 i 个节点(curr)之间,即让 prev._next 指向新节点,新节点的 _next 指向原 curr。
原代码中关键错误出现在 insert 方法的 else 分支:
curr = _List_Node(value, prev) # ❌ 错误:将新节点的 next 指向 prev(前驱),造成循环或丢失链
这不仅破坏了链表结构,还使新节点完全脱离原链表——因为 curr 是局部变量,赋值后未更新任何链表指针(如 prev._next),因此 LD 对象本身毫无变化,输出仍是 11 → 22 → 33。
✅ 正确做法是:
立即学习“Python免费学习笔记(深入)”;
- 遍历至索引 i-1 处的节点(即前驱),记为 prev
- 创建新节点 new_node = _List_Node(value, curr),其中 curr = prev._next(即原第 i 个节点)
- 更新 prev._next = new_node
- 若插入位置为尾部(i == self._count),还需同步更新 self._rear
以下是修复后的完整 insert 方法实现(已适配题设类结构,含边界处理与 rear 维护):
def insert(self, i, value):
"""
-------------------------------------------------------
A copy of value is added to index i, following values are pushed right.
If i outside of range of -len(list) to len(list) - 1, the value is
prepended or appended as appropriate.
Use: lst.insert(i, value)
-------------------------------------------------------
Parameters:
i - index value (int)
value - a data element (?)
Returns:
None
-------------------------------------------------------
"""
# 处理负索引:转换为等效正索引
if i < 0:
i += self._count
# 边界情况:头插
if i <= 0:
self.prepend(value)
# 尾插
elif i >= self._count:
self.append(value)
# 中间插入
else:
# 定位到索引 i-1 的节点(prev)
prev = self._front
for _ in range(i - 1):
prev = prev._next
curr = prev._next # 原第 i 个节点
new_node = _List_Node(value, curr)
prev._next = new_node
self._count += 1? 关键注意事项:
- 索引有效性校验:负索引需先转换(i += self._count),避免越界访问;
- 前驱定位:务必停在 i-1 位置,而非 i;使用 for 循环比 while 更清晰可控;
- 指针更新顺序:先保存 curr = prev._next,再创建 new_node 并设置其 _next = curr,最后更新 prev._next = new_node;
- 链表完整性:本实现未修改 _rear(因中间插入不涉及尾部),但若支持 i == self._count 的尾插,append 已确保 _rear 正确更新;
- 时间复杂度:O(n),符合单链表特性;无法像数组一样 O(1) 随机访问。
验证示例:
LD = List() LD.append(11) LD.append(22) LD.append(33) LD.insert(1, 77) # 在索引1处插入 → [11, 77, 22, 33] LD.printf() # 输出:11\n77\n22\n33
掌握这一模式后,你不仅能修复插入逻辑,还能举一反三实现删除、查找等核心操作——链表操作的本质,始终是精准控制节点间的 _next 引用关系。


















