LeetCode删除链表倒数第N个节点:修改curr为何会同步改变head?
为什么修改curr指针的属性会同步改动head指向的原链表
核心原因是JavaScript中对象类型按引用传递,遍历用的curr从来不是原节点的独立副本,只是指向原链表节点的引用。
你可以先看这段极简的验证代码:
// 模拟一个链表节点 const node = { val: 1, next: { val: 2, next: { val:3, next: null } } } const curr = node; // 初始化遍历指针 curr.next = curr.next.next; // 执行删除下一个节点的操作 console.log(node.next.val); // 输出3,原节点的结构直接被修改了
具体到链表遍历的逻辑,你可以这么理解:
- 链表的每一个节点都是独立存储在内存里的对象,
head变量本身也只是存了头节点的内存地址,不是存了整个链表的拷贝 - 当你写
let curr = head启动遍历时,只是让curr这个变量也存了和head一模一样的内存地址,两个变量指向完全同一个头节点对象 - 后续做
curr = curr.next移动指针时,只是把curr里存的地址更新成下一个节点的内存地址,全程没有生成任何新的节点副本,curr从头到尾都只是一个“路标”,指向的全是原链表里本来就存在的节点 - 当你执行
curr.next = curr.next.next时,本质是顺着curr存的内存地址找到原链表里的对应节点,直接修改了这个节点的next属性——这个节点本来就是原链表的组成部分,修改它的连接关系自然会直接反映在整个head对应的链表结构上。
只有一种情况你改curr不会影响原链表:你把curr重新赋值为一个全新创建的节点对象,这时候curr指向的是一块新的内存地址,和原链表断了关联,后续怎么改都不会碰原链表的结构:
curr = { val: 999, next: null }; // 这时候curr和原链表没关系了,改动不会影响head
很多新手刚学链表的时候会误以为遍历指针是拿了原链表的复印件改,实际上所有遍历指针都只是指着原节点的“地址标签”,顺着标签找到原节点改连接关系,改的就是原链表本身。
内容的提问来源于stack exchange,提问作者user16589580
相关产品推荐
相关产品推荐

