向链表推入多个节点后head仍为null?相关技术疑问
链表代码问题解答
问题背景
执行以下代码后,调用print方法可正常输出节点值,但打印ll.head却显示为null:
class node { constructor(val) { this.data = val; this.next = null; } } class linkedlist { constructor() { this.head = null; } push = (val) => { if (!this.head) { this.head = new node(val); return; } let temp = new node(val); temp.next = this.head; this.head = temp; } print = () => { while (this.head) { console.log(this.head.data); this.head = this.head.next; } } } var ll = new linkedlist(); var n = 5; while (n--) ll.push(n); ll.print(); // 0 1 2 3 4 console.log(ll.head); // null
疑问
- 为何
head会变为null?是否是因为使用let声明类变量导致的? head必须为全局作用域才能修改其值吗?- 为何
print函数能正常运行?
解答
1. head变为null的原因
和let声明无关,问题出在print方法的实现上:
print = () => { while (this.head) { console.log(this.head.data); this.head = this.head.next; // 直接修改了实例的head指针 } }
遍历链表时,你直接移动了this.head这个实例属性。每次循环this.head都会指向当前节点的下一个节点,当遍历到最后一个节点时,this.head.next是null,循环结束后this.head就被设为null了。
你的代码里并没有用let声明类变量,head是在构造函数中定义的实例属性,和let完全没关系。
2. head不需要全局作用域就能修改
head作为链表类的实例属性,只要在类的方法中通过this.head就能直接修改,和全局作用域无关。你应该避免直接修改head指针来遍历,而是用临时变量代替:
print = () => { let current = this.head; // 用临时变量遍历,保留原head指针 while (current) { console.log(current.data); current = current.next; } }
这样遍历完成后,this.head依然指向链表的第一个节点,不会变成null。
3. print函数能正常运行的原因
遍历过程中,this.head从第一个节点开始,每次循环都能获取当前节点的data并输出,然后移动到下一个节点。直到this.head变成null时循环终止,整个过程覆盖了所有节点,所以能正常输出0到4。只是遍历结束后,原head指针已经移出链表范围,导致后续打印ll.head为null。
内容的提问来源于stack exchange,提问作者Mccranky83
相关产品推荐
相关产品推荐

