Skip to main content

--description--

The next important method that any implementation of a linked list will need is a remove method. This method should take the element we want to remove as an argument, and then search the list to find and remove the node that contains that element.

Whenever we remove a node from a linked list, it's important that we don't accidentally orphan the rest of the list in doing so. Recall that every node's next property points to the node that follows it in the list. If we're removing the middle element, say, we'll want to make sure that we have a connection from that element's previous node's next property to the middle element's next property (which is the next node in the list!)

This might sound really confusing, so let's return to the conga line example so we have a good conceptual model. Picture yourself in a conga line, and the person directly in front of you leaves the line. The person who just left the line no longer has her hands on anyone in line--and you no longer have your hands on the person that left. You step forward and put your hands on next person you see.

If the element we wish to remove is the head element, we reassign the head to the second node of the linked list.

--instructions--

Write a remove method that takes an element and removes it from the linked list.

Note: The length of the list should decrease by one every time an element is removed from the linked list.

--hints--

Your LinkedList class should have a remove method.

assert(
(function () {
var test = new LinkedList();
return typeof test.remove === 'function';
})()
);

Your remove method should reassign head to the second node when the first node is removed.

assert(
(function () {
var test = new LinkedList();
test.add('cat');
test.add('dog');
test.remove('cat');
return test.head().element === 'dog';
})()
);

Your remove method should decrease the length of the linked list by one for every node removed.

assert(
(function () {
var test = new LinkedList();
test.add('cat');
test.add('dog');
test.add('hamster');
test.remove('cat');
test.remove('fish');
return test.size() === 2;
})()
);

Your remove method should reassign the reference of the previous node of the removed node to the removed node's next reference.

assert(
(function () {
var test = new LinkedList();
test.add('cat');
test.add('dog');
test.add('snake');
test.add('kitten');
test.remove('snake');
return test.head().next.next.element === 'kitten';
})()
);

Your remove method should not change the linked list if the element does not exist in the linked list.

assert(
(function () {
var test = new LinkedList();
test.add('cat');
test.add('dog');
test.add('kitten');
test.remove('elephant');
return (
JSON.stringify(test.head()) ===
'{"element":"cat","next":{"element":"dog","next":{"element":"kitten","next":null}}}'
);
})()
);

--seed--

--seed-contents--

function LinkedList() {
var length = 0;
var head = null;

var Node = function(element){
this.element = element;
this.next = null;
};

this.size = function(){
return length;
};

this.head = function(){
return head;
};

this.add = function(element){
var node = new Node(element);
if(head === null){
head = node;
} else {
var currentNode = head;

while(currentNode.next){
currentNode = currentNode.next;
}

currentNode.next = node;
}

length++;
};

this.remove = function(element){
// Only change code below this line

// Only change code above this line
};
}

--solutions--

function LinkedList() {
var length = 0;
var head = null;

var Node = function(element){
this.element = element;
this.next = null;
};

this.size = function(){
return length;
};

this.head = function(){
return head;
};

this.add = function(element){
var node = new Node(element);
if(head === null){
head = node;
} else {
var currentNode = head;

while(currentNode.next){
currentNode = currentNode.next;
}

currentNode.next = node;
}

length++;
};

this.remove = function(element){
if (head === null) {
return;
}
var previous;
var currentNode = head;

while (currentNode.next !== null && currentNode.element !== element) {
previous = currentNode;
currentNode = currentNode.next;
}

if (currentNode.next === null && currentNode.element !== element) {
return;
}
else if (previous) {
previous.next = currentNode.next;
} else {
head = currentNode.next;
}

length--;
};
}