尝试制作一个 Node class 函数,该函数接受一组项目并将它们全部推送到链表
Trying to make a Node class function that takes an array of items and pushes them all to a linked list
这是我到目前为止编写的代码。我认为我不一定在 'Node' 函数中使用循环的正确轨道...
function LinkedList() {
this.head = null;
this.tail = null;
this.length = 0;
}
function Node(...val) {
if (Array.isArray(val)) {
for (let i = 0; i < val.length; i++) {
this.push(val[i])
}
}
this.value = val;
this.next = null;
}
LinkedList.prototype.push = function(val) {
let newNode = new Node(val);
if(!this.head) {
this.head = newNode;
return this.head;
}
let tail = this.head;
while (tail.next !== null) {
tail = tail.next;
}
tail.next = newNode;
return this.head;
};
这是我尝试运行的测试...
const newList = new LinkedList(5, 1, 2, 6, 8);
console.log(newList.head.value);
console.log(newList.head.next.value);
console.log(newList.head.next.next.value);
console.log(newList.head.next.next.next.value);
console.log(newList.head.next.next.next.next.value);
console.log(newList.head.next.next.next.next.next);
控制台日志的输出只是“无法读取 null 的属性(读取 'value')。
有人可以指出我做错了什么或下一步要去哪里吗?感谢您的宝贵时间!
问题是您的 LinkedList
构造函数没有任何参数,因此当您使用 new LinkedList(5, 1, 2, 6, 8);
构造它时,这些参数将被忽略。
您可能放错了参数处理的位置,将其放在 Node
构造函数中,而它应该放在 LinkedList
构造函数中。
因此移动该代码和参数定义,它将起作用。
其他一些需要改进的地方:
没有必要做 Array.isArray
检查,因为 ...val
参数声明将 总是 给你一个数组该函数被调用——当没有传递参数时它的长度可能为 0,但它仍然是一个数组。
push
方法不应该经过一个循环。您已经有一个 tail
参考,所以请使用它。
push
方法应该更新 length
属性 -- 因为你有它。
push
方法不应该 return 任何东西。修改是在 LinkedList
实例中完成的,调用者实际上不必知道创建的 Node
实例。
这是工作版本:
function LinkedList(...val) {
this.head = null;
this.tail = null;
this.length = 0;
for (let i = 0; i < val.length; i++) {
this.push(val[i]);
}
}
function Node(val) {
this.value = val;
this.next = null;
}
LinkedList.prototype.push = function(val) {
let newNode = new Node(val);
if (!this.head) {
this.head = newNode;
} else {
this.tail.next = newNode;
}
this.tail = newNode;
this.length++;
};
const newList = new LinkedList(5, 1, 2, 6, 8);
console.log(newList.head.value);
console.log(newList.head.next.value);
console.log(newList.head.next.next.value);
console.log(newList.head.next.next.next.value);
console.log(newList.head.next.next.next.next.value);
console.log(newList.head.next.next.next.next.next);
现代化
由于您的代码使用扩展语法,因此您没有理由不也使用 class
语法和 for..of
循环。
并且为了避免调用者必须知道 Node
实例,使用 Symbol.iterator
:
让你的 LinkedList
class 可迭代
class LinkedList {
constructor(...values) {
this.head = null;
this.tail = null;
this.length = 0;
for (let value of values) {
this.push(value);
}
}
push(val) {
let newNode = new Node(val);
if (!this.head) {
this.head = newNode;
} else {
this.tail.next = newNode;
}
this.tail = newNode;
this.length++;
}
*[Symbol.iterator]() {
let node = this.head;
while (node) {
yield node.value;
node = node.next;
}
}
}
class Node {
constructor(val) {
this.value = val;
this.next = null;
}
}
const newList = new LinkedList(5, 1, 2, 6, 8);
for (let value of newList) {
console.log(value);
}
这是我到目前为止编写的代码。我认为我不一定在 'Node' 函数中使用循环的正确轨道...
function LinkedList() {
this.head = null;
this.tail = null;
this.length = 0;
}
function Node(...val) {
if (Array.isArray(val)) {
for (let i = 0; i < val.length; i++) {
this.push(val[i])
}
}
this.value = val;
this.next = null;
}
LinkedList.prototype.push = function(val) {
let newNode = new Node(val);
if(!this.head) {
this.head = newNode;
return this.head;
}
let tail = this.head;
while (tail.next !== null) {
tail = tail.next;
}
tail.next = newNode;
return this.head;
};
这是我尝试运行的测试...
const newList = new LinkedList(5, 1, 2, 6, 8);
console.log(newList.head.value);
console.log(newList.head.next.value);
console.log(newList.head.next.next.value);
console.log(newList.head.next.next.next.value);
console.log(newList.head.next.next.next.next.value);
console.log(newList.head.next.next.next.next.next);
控制台日志的输出只是“无法读取 null 的属性(读取 'value')。
有人可以指出我做错了什么或下一步要去哪里吗?感谢您的宝贵时间!
问题是您的 LinkedList
构造函数没有任何参数,因此当您使用 new LinkedList(5, 1, 2, 6, 8);
构造它时,这些参数将被忽略。
您可能放错了参数处理的位置,将其放在 Node
构造函数中,而它应该放在 LinkedList
构造函数中。
因此移动该代码和参数定义,它将起作用。
其他一些需要改进的地方:
没有必要做
Array.isArray
检查,因为...val
参数声明将 总是 给你一个数组该函数被调用——当没有传递参数时它的长度可能为 0,但它仍然是一个数组。push
方法不应该经过一个循环。您已经有一个tail
参考,所以请使用它。push
方法应该更新length
属性 -- 因为你有它。push
方法不应该 return 任何东西。修改是在LinkedList
实例中完成的,调用者实际上不必知道创建的Node
实例。
这是工作版本:
function LinkedList(...val) {
this.head = null;
this.tail = null;
this.length = 0;
for (let i = 0; i < val.length; i++) {
this.push(val[i]);
}
}
function Node(val) {
this.value = val;
this.next = null;
}
LinkedList.prototype.push = function(val) {
let newNode = new Node(val);
if (!this.head) {
this.head = newNode;
} else {
this.tail.next = newNode;
}
this.tail = newNode;
this.length++;
};
const newList = new LinkedList(5, 1, 2, 6, 8);
console.log(newList.head.value);
console.log(newList.head.next.value);
console.log(newList.head.next.next.value);
console.log(newList.head.next.next.next.value);
console.log(newList.head.next.next.next.next.value);
console.log(newList.head.next.next.next.next.next);
现代化
由于您的代码使用扩展语法,因此您没有理由不也使用 class
语法和 for..of
循环。
并且为了避免调用者必须知道 Node
实例,使用 Symbol.iterator
:
LinkedList
class 可迭代
class LinkedList {
constructor(...values) {
this.head = null;
this.tail = null;
this.length = 0;
for (let value of values) {
this.push(value);
}
}
push(val) {
let newNode = new Node(val);
if (!this.head) {
this.head = newNode;
} else {
this.tail.next = newNode;
}
this.tail = newNode;
this.length++;
}
*[Symbol.iterator]() {
let node = this.head;
while (node) {
yield node.value;
node = node.next;
}
}
}
class Node {
constructor(val) {
this.value = val;
this.next = null;
}
}
const newList = new LinkedList(5, 1, 2, 6, 8);
for (let value of newList) {
console.log(value);
}