You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单链表push方法中this.tail.next为何能将节点添加到this.head链表中?

核心原理

这个现象的本质是JavaScript中引用类型的存储特性,以及单链表的链式结构设计,head和tail只是标记链表首尾位置的指针,二者不需要指向同一个对象也能操作链表。

我们可以拆解两次push操作的完整执行流程,就能清晰看到逻辑:

第一次调用list.push('hello')

此时链表为空,this.head为null,走if分支:

  1. 新建值为hello的Node实例(我们简称它为节点A),它是一块独立的内存空间,初始next为null
  2. this.head = node:将head指针指向节点A的内存地址
  3. this.tail = this.head:将tail指针也指向节点A的内存地址,此时head和tail指向同一个对象
  4. 长度加1,完成第一次插入

此时链表结构为:
head → 节点A(val:hello, next:null) ← tail

第二次调用list.push('goodbye')

此时this.head已存在,走else分支:

  1. 新建值为goodbye的Node实例(简称节点B),初始next为null
  2. 关键第一步:执行this.tail.next = node,此时tail还指向节点A,所以这一步实际是给节点A的next属性赋值为节点B的内存地址,到这一步就已经把节点B挂到了原链表的末尾,和head对应的链表完成了关联
  3. 关键第二步:执行this.tail = node,只是把tail指针从节点A移动到节点B,更新末尾标记,这一步不会破坏已经建立的节点A和节点B的关联
  4. 长度加1,完成第二次插入

此时链表结构为:
head → 节点A(val:hello, next:节点B) → 节点B(val:goodbye, next:null) ← tail

误区澄清

你疑惑的核心是混淆了指针和节点本身的关系:
head和tail只是两个独立的指针(可以理解为贴在节点上的便利贴),本身不是链表的组成部分。把tail从节点A撕下来贴到节点B上,完全不会影响节点A的next已经指向节点B的关联,所以从head出发顺着next遍历,依然能访问到所有节点。

你可以自行验证:第二次push完成后打印list.head.next.val,输出结果就是goodbye,也能证明节点A的next已经正确关联了新节点。

注:你贴的代码存在语法错误,SinglyLinkedList类的闭合花括号位置错误,应该在push方法结束后、let list声明前补全类的闭合。


内容的提问来源于stack exchange,提问作者fatih.jsx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 16:24:01