pop(){
if(this.head == null){
return undefined;
}
else if(this.head == this.tail){
this.head = null;
this.tail = null;
this.length--
}
else{
let temp = this.head;
let pre = this.head;
while(temp.next){
pre = temp;
temp = temp.next;
}
this.tail = pre;
this.tail.next = null;
this.length--
}
I'm more concerned about the condition in which there's only one item inside the linked list.
CodePudding user response:
The code is fine.
Here is a program that will test the implementation. Of course, the class needs to be completed with some other methods. The return undefined
can be simplified to just return
.
class Node {
constructor(value, next=null) {
this.value = value;
this.next = next;
}
}
class LinkedList {
constructor(...values) {
this.head = this.tail = null;
this.length = 0;
for (value of values) {
this.push(value);
}
}
push(value) {
if (this.tail) {
this.tail = this.tail.next = new Node(value);
} else {
this.head = this.tail = new Node(value);
}
this.length ;
}
pop(){
if (this.head == null){
return;
}
else if (this.head == this.tail){
this.head = null;
this.tail = null;
this.length--
}
else {
let temp = this.head;
let pre = this.head;
while(temp.next){
pre = temp;
temp = temp.next;
}
this.tail = pre;
this.tail.next = null;
this.length--
}
}
*[Symbol.iterator]() {
for (let node = this.head; node; node = node.next) {
yield node.value;
}
}
consistent() {
if (this.length != [...this].length) throw "length is inconsistent";
if (this?.tail?.next) throw "tail is inconsistent";
}
}
// Perform tests by doing the same operations on a native array simultaneously and comparing the result
let list = new LinkedList;
let arr = [];
for (let i = 0; i < 10000; i ) {
let choice = Math.random() > 0.5 && list.length < 10;
let value = Math.floor(Math.random() * 100);
if (choice) {
list.push(value);
arr.push(value);
} else {
list.pop();
arr.pop();
}
list.consistent();
if (JSON.stringify(arr) !== JSON.stringify([...list])) throw "Difference detected";
}
console.log("Tests done: all OK");
In JavaScript it is customary for pop()
to return the value that was popped (this is not the case in every language, e.g. C ), as this is how the native array prototype defines pop
. So you might want to consider to apply the same principle on your pop
method.
Here is a version of the above code that includes that feature (and tests it):
class Node {
constructor(value, next=null) {
this.value = value;
this.next = next;
}
}
class LinkedList {
constructor(...values) {
this.head = this.tail = null;
this.length = 0;
for (value of values) {
this.push(value);
}
}
push(value) {
if (this.tail) {
this.tail = this.tail.next = new Node(value);
} else {
this.head = this.tail = new Node(value);
}
this.length ;
}
pop() {
if (this.head == null){
return;
}
const value = this.tail.value;
if (this.head == this.tail){
this.head = null;
this.tail = null;
} else {
let temp = this.head;
let pre = this.head;
while(temp.next){
pre = temp;
temp = temp.next;
}
this.tail = pre;
this.tail.next = null;
}
this.length--;
return value;
}
*[Symbol.iterator]() {
for (let node = this.head; node; node = node.next) {
yield node.value;
}
}
consistent() {
if (this.length != [...this].length) throw "length is inconsistent";
if (this?.tail?.next) throw "tail is inconsistent";
}
}
let list = new LinkedList;
let arr = [];
for (let i = 0; i < 10000; i ) {
let choice = Math.random() > 0.5 && list.length < 10;
let value = Math.floor(Math.random() * 100);
if (choice) {
list.push(value);
arr.push(value);
} else {
if (list.pop() !== arr.pop()) throw "Inconsistent pop return value";
}
list.consistent();
if (JSON.stringify(arr) !== JSON.stringify([...list])) throw "JSON is different";
}
console.log("tests done");
CodePudding user response:
In the case when there is only one item in the list, this might not work.
This piece of code will not run:
while(temp.next){
pre = temp;
temp = temp.next;
}
The length will be reduced. But i guess you will have to point both this.head
and this.tail
to null
, in the case length is 1.