This community-built FAQ covers the “Swap Elements in a Linked List” code challenge in JavaScript. You can find that challenge here, or pick any challenge you like from our list.
Top Discussions on the JavaScript challenge Swap Elements in a Linked List
There are currently no frequently asked questions or top answers associated with this challenge – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this challenge. Ask a question or post a solution by clicking reply (
) below.
If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this challenge, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.
Join the Discussion. Help a fellow learner on their journey.
Ask or answer a question about this exercise by clicking reply (
) below!
You can also find further discussion and get answers to your questions over in #get-help.
Agree with a comment or answer? Like (
) to up-vote the contribution!
Need broader help or resources? Head to #get-help and #community:tips-and-resources. If you are wanting feedback or inspiration for a project, check out #project.
Looking for motivation to keep learning? Join our wider discussions in #community
Learn more about how to use this guide.
Found a bug? Report it online, or post in #community:Codecademy-Bug-Reporting
Have a question about your account or billing? Reach out to our customer support team!
None of the above? Find out where to ask other questions here!
Hi, there is my solution. The trickiest part was that provided List doesn’t contain constructor with “head”.
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
function swapNodes(list, data1, data2) {
let node1 = list
let node1prev = null
let node2 = list
let node2prev = null
// STEP I.
while (node1 !== null) {
if (node1.data === data1) {
break
}
node1prev = node1
node1 = node1.getNextNode()
}
while (node2 !== null) {
if (node2.data === data2) {
break
}
node2prev = node2
node2 = node2.getNextNode()
}
// STEP II.
if (node1prev === null) {
list = node2
} else {
node1prev.setNextNode(node2)
}
if (node2prev === null) {
list = node1
} else {
node2prev.setNextNode(node1)
}
// STEP III.
let temp = node1.getNextNode()
node1.setNextNode(node2.getNextNode())
node2.setNextNode(temp)
// return statement
return list
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6])
let retList = swapNodes(exampleList, 2, 5)
console.log(retList)
module.exports = swapNodes;
Does this count as cheating!
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
function swapNodes(list, data1, data2) {
let li = list;
let arr = [];
while ( li ) {
arr.push(li.data)
li = li.next;
}
let index1 = arr.indexOf(data1);
let index2 = arr.indexOf(data2);
[ arr[index1], arr[index2] ] = [ arr[index2], arr[index1] ]
return makeLinkedList(arr)
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6])
let retList = swapNodes(exampleList, 2, 5)
console.log(retList)
// Leave this so we can test your code:
module.exports = swapNodes;
2 Likes
I swapped the .data
of the nodes instead of actually swapping the nodes.
I created a helper method called .search
to get a node with a specific value for the .data
first.
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
function search(dataValue) {
let current = this;
while (!((current === null) || (current === undefined))) {
if (current.data === dataValue) {
return current;
}
// set up for next iteration >> move to next node
current = current.next;
}
return 0;
}
function swapNodes(list, data1, data2) {
if (!list.search) {
list.search = search;
}
// get the nodes
let node1 = list.search(data1);
let node2 = list.search(data2);
// swap the .data
if (node1 && node2) {
node1.data = data2;
node2.data = data1;
}
return list;
}
function printList(linkedList) {
let current = linkedList;
let started = false;
while (!((current === null) || (current === undefined))) {
if (started) {
process.stdout.write(" -> ");
}
else {
started = true;
}
process.stdout.write(current.data + "");
// set up for next iteration >> move to next node
current = current.next;
}
process.stdout.write("\n");
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6]);
//printList(exampleList);
let retList = swapNodes(exampleList, 2, 5);
//printList(retList);
// Leave this so we can test your code:
module.exports = swapNodes;
Here’s proof that it works:
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
function makeLinkedList(array) {
let previousNode;
let currentNode;
let firstNode;
for (let x of array) {
currentNode = new Node(x);
if (!firstNode) {
firstNode = currentNode;
}
else {
previousNode.next = currentNode;
}
// set up for next iteration
previousNode = currentNode;
}
return firstNode
}
function search(dataValue) {
let current = this;
while (!((current === null) || (current === undefined))) {
if (current.data === dataValue) {
return current;
}
// set up for next iteration >> move to next node
current = current.next;
}
return 0;
}
function swapNodes(list, data1, data2) {
if (!list.search) {
list.search = search;
}
// get the nodes
let node1 = list.search(data1);
let node2 = list.search(data2);
// swap the .data
if (node1 && node2) {
node1.data = data2;
node2.data = data1;
}
return list;
}
function printList(linkedList) {
let current = linkedList;
let started = false;
let output = "";
while (!((current === null) || (current === undefined))) {
if (started) {
output = output + " -> ";
}
else {
started = true;
}
output = output + current.data;
// set up for next iteration >> move to next node
current = current.next;
}
console.log(output);
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6]);
printList(exampleList);
let retList = swapNodes(exampleList, 2, 5);
console.log("swapNodes(exampleList, 2, 5)");
printList(retList);
I had to come up with a makeLinkedList
function for that demo.
1 Like
Yes, I think that’s cheating a little (since you didn’t have to write your own makeLinkedList
function).
But I still like that approach.
1 Like
Short answer, yes. It’s also a very inefficient way to swap elements of a linked list.
1 Like
Swapping the data may seemingly accomplish the task, but does it really? Swapping the position of the nodes in the list is the true task. In an actual linked list application, each node may have additional unique properties. Swapping the data between two nodes would create a mess.
1 Like
Admittedly, this challenge is tough without a linked list class with built-in functions, but in reality, a linked list is nothing more than a head node with a pointer to a next node. It may continue on, it may not. It may only be the single node. It really doesn’t matter though for the challenge. If you have the head, you have the entire list. My code below. Could probably do with some re-factoring, but that will have to wait.
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
function swapNodes(list, data1, data2) {
if(data1 === data2) return list;
let current = list;
let found1 = null;
let found2 = null;
let prev1 = null;
let prev2 = null;
if(current === list && data1 === current.data) {
found1 = current;
}
if(current === list && data2 === current.data) {
found2 = current;
}
while (current.next != null) {
if(current.next.data === data1 && !(found1)) {
prev1 = current;
found1 = current.next;
}
if(current.next.data === data2 && !found2) {
prev2 = current;
found2 = current.next;
}
if(found1 != null && found2 != null) break;
current = current.next;
}
if(found1 && found2) {
if(prev1 && prev2){
let temp = found1.next;
prev1.next = found2;
found1.next = found2.next;
if(prev2 === found1) {
prev2.next = found2.next;
found2.next = found1;
} else {
prev2.next = found1;
found2.next = temp;
}
} else {
// swap head
if(found2 === list) [found1, found2, prev1, prev2] = [found2, found1, prev2, prev1];
let temp = found1.next;
found1.next = found2.next;
if(prev2 === found1) {
prev2.next = found2.next;
found2.next = found1;
} else {
prev2.next = found1;
found2.next = temp;
}
list = found2;
}
}
return list;
}
// View result
function printLlist(lList) {
let current = lList;
let llistToString = current.data;
while(current.next != null) {
llistToString += ` -> ${current.next.data}`;
current = current.next;
}
console.log(llistToString)
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
let retList = swapNodes(exampleList, 0, 3);
printLlist(retList);
// Leave this so we can test your code:
module.exports = swapNodes;
Output:
2 → 1 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 0
1 Like
I tried to swap the nodes themselves this time (by changing the .next
)
I also made helper methods for getting a node given its value, and finding the previous node in the list
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
function search(dataValue) {
let current = this;
while (current) {
if (current.data === dataValue) {
return current;
}
// set up for next iteration >> move to mext node
current = current.next;
}
return 0;
}
function getPreviousNode(node) {
let current = this;
while (current) {
if (current.next === node) {
return current;
}
// set up for next iteration >> move to mext node
current = current.next;
}
return 0;
}
function swapNodes(list, data1, data2) {
if (data1 == data2) {
return list;
}
let newList = list;
// add methods
if (!list.search) {
list.search = search;
}
if (!list.getPreviousNode) {
list.getPreviousNode = getPreviousNode;
}
// get the nodes
let node1 = list.search(data1);
let node2 = list.search(data2);
let before1;
let before2;
if (node1 !== list) {
before1 = list.getPreviousNode(node1);
}
if (node2 !== list) {
before2 = list.getPreviousNode(node2);
}
let after1 = node1.next;
let after2 = node2.next;
// deal with cases when node1 and node2 are adjacent
if (after1 == node2) {
if (before1) {
before1.next = node2;
}
node2.next = node1;
node1.next = after2;
}
else if (after2 == node1) {
if (before2) {
before2.next = node1;
}
node1.next = node2;
node2.next = after1;
}
// deal with non-adjacent node1 and node2
else {
if (before1) {
before1.next = node2;
}
node1.next = after2;
if (before2) {
before2.next = node1;
}
node2.next = after1;
}
// if node1 or node2 is the list (head node)
if (list === node1) {
newList = node2;
}
else if (list === node2) {
newList = node1;
}
return newList;
}
function printList(linkedList) {
let current = linkedList;
let started = false;
while (current) {
if (started) {
process.stdout.write(" -> ");
}
else {
started = true;
}
process.stdout.write(current.data + "");
// set up for next iteration >> move to mext node
current = current.next;
if (current == linkedList) {
process.stdout.write(" -> (Circular List)");
break;
}
}
process.stdout.write("\n");
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6]);
printList(exampleList);
let retList = swapNodes(exampleList, 2, 5);
printList(retList);
// Leave this so we can test your code:
module.exports = swapNodes;
1 Like
I found my Error. I couldn’t swap the first with the second element. I deleted my posts, so you don’t have to look at broken code. I think you can still access thorough the edit history.
So finally, here is my working solution:
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
function swapNodes(list, data1, data2) {
let predata1, predata2, curdata1, curdata2, postdata1, postdata2, temp, newhead;
let data1found = false;
let data2found = false;
/* Sort out insufficient inputs */
if (data1 === data2 || list === null || data1 === null || data2 === null) {
return list;
};
/* Make a new head so the head never gets swapped */
newhead = new Node(null);
newhead.next = list;
temp = newhead;
/* See if the swapping nodes exist and save their parent */
while (temp.next != null) {
if (temp.next.data === data1 && !data1found) {
predata1 = temp;
data1found = true;
}
if (temp.next.data === data2 && !data2found) {
predata2 = temp;
data2found = true;
}
temp = temp.next;
}
if (!data1found || !data2found) {
return list;
}
/* Split the Parent Node, the current node and the child node in different variables for a better overview */
curdata1 = predata1.next;
curdata2 = predata2.next;
postdata1 = curdata1.next;
postdata2 = curdata2.next;
/* Special cases, if the swapping nodes are consecutive */
if (predata2 === curdata1) {
curdata1.next = postdata2;
predata1.next = curdata2;
curdata2.next = curdata1;
return newhead.next;
}
if (predata1 === curdata2) {
curdata2.next = postdata1;
predata2.next = curdata1;
curdata1.next = curdata2;
return newhead.next;
}
/* standard swapping */
curdata1.next = postdata2;
curdata2.next = postdata1;
predata2.next = curdata1;
predata1.next = curdata2;
return newhead.next;
}
let exampleList = makeLinkedList([2,0,1]);
let retList = swapNodes(exampleList, 0,1);
retList.print();
// Leave this so we can test your code:
module.exports = swapNodes;
1 Like
function swapNodes(list, data1, data2) {
let node1 = list;
let node2 = list;
while(!(node1.data==data1 & node2.data == data2)){
if(node1.data!=data1){
node1 = node1.next;
}
if(node2.data != data2){
node2 = node2.next;
}
}
node1.data = data2;
node2.data = data1;
return list;
}
function swapNodes(list, data1, data2) {
if (!data1 || !data2 || data1 === data2) return list;
let head = list;
let prevA = null;
let currA = head;
while (currA) {
if (currA.data === data1) break;
prevA = currA;
currA = currA.next;
};
let prevB = null;
let currB = head;
while (currB) {
if (currB.data === data2) break;
prevB = currB;
currB = currB.next;
};
if (!currA || !currB) return list;
prevA ? prevA.next = currB : head = currB;
prevB ? prevB.next = currA : head = currA;
let tempNode = currB.next;
currB.next = currA.next;
currA.next = tempNode;
return head;
};
Hello ,it is my solution:
const Node = require(‘./Node.js’);
const makeLinkedList = require(‘./makeLinkedList.js’);
function swapNodes(list, data1, data2) {
let prevNode1 = null;
let prevNode2 = null;
let node1 = list;
let node2 = list;
while (node1 && node1.data !== data1) {
prevNode1 = node1;
node1 = node1.next;
}
while (node2 && node2.data !== data2) {
prevNode2 = node2;
node2 = node2.next;
}
// If either of the nodes is not found, return the original list
if (!node1 || !node2) {
return list;
}
// If node1 is the head, update the head to point to node2
if (prevNode1 === null) {
list = node2;
} else {
prevNode1.next = node2;
}
// If node2 is the head, update the head to point to node1
if (prevNode2 === null) {
list = node1;
} else {
prevNode2.next = node1;
}
// Swap the next pointers of node1 and node2
let temp = node1.next;
node1.next = node2.next;
node2.next = temp;
return list;
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6])
let retList = swapNodes(exampleList, 2, 5)
// Leave this so we can test your code:
module.exports = swapNodes;
I did this by creating a LinkedList
class, but I guess that wasn’t necessary since I should have returned the head node instead of a linked list.
I made finding the relevant nodes and their previous nodes a separate function.
code
const Node = require('./Node.js');
const makeLinkedList = require('./makeLinkedList.js');
/*
function Node(data) { // constructor for Node
this.data = data;
this.next = null;
}
*/
class LinkedList {
constructor(headNode) {
this.head = headNode ? headNode : null;
}
// make the LinkedList act like the head node:
get data() { return (this.head) ? this.head.data : null; }
get next() { return (this.head) ? this.head.next : null; }
getNodeByData(data) {
let current = this.head;
while(current) {
if (current.data === data) {
return current;
}
current = current.next;
}
return null;
}
toString() {
let current = this.head;
let output = "";
if (current) {
output += current.data;
current = current.next;
}
while(current) {
output += " -> " + current.data;
current = current.next;
}
return output;
}
get length() { // I used this to check if there's a loop
const maxIterations = 100; // indicates loop
let current = this.head;
let count = 0;
while (current && count < maxIterations) {
count++;
current = current.next;
}
return count;
}
static from(iterable) {
const list = new LinkedList();
let previous = null;
for (let value of iterable) {
const node = new Node(value);
if (previous) {
previous.next = node;
}
else {
list.head = node;
}
previous = node;
}
return list;
}
}
//const makeLinkedList = (it) => LinkedList.from(it);
function getNodeAndPreviousByData(list, data) {
let previous = null;
let current = list.head;
let i = 0;
while(current) {
if (current.data === data) {
break;
}
previous = current;
current = current.next;
i++;
}
return [current, previous, i];
}
const show = (obj) => obj ? obj.data : "null";
function swapNodes(list, data1, data2) {
if (!(list instanceof LinkedList)) {
list = new LinkedList(list);
}
let set1 = getNodeAndPreviousByData(list, data1);
let set2 = getNodeAndPreviousByData(list, data2);
// if set1 is after set2, then swap set1, set2
if (set1[2] > set2[2]) {
const temp = set1;
set1 = set2;
set2 = temp;
}
const node1 = set1[0];
const before1 = set1[1];
const node2 = set2[0];
const before2 = set2[1];
// exit function if no nodes are found or are same node
if ((!node1 || !node2) || (node1 === node2)) {
return list;
}
else if (node1.next === node2) { // the notes are consecutive nodes
if (before1) {
before1.next = node2;
}
node1.next = node2.next;
node2.next = node1;
}
else { // the nodes are not consecutive nodes
let temp = node1.next;
node1.next = node2.next;
node2.next = temp;
if (before1) {
before1.next = node2;
}
if (before2) {
before2.next = node1;
}
}
if (list.head === node1) {
list.head = node2;
}
return list;
//return list.head;
}
let exampleList = makeLinkedList([1, 2, 3, 4, 5, 6]);
let retList = swapNodes(exampleList, 2, 5);
//console.log(retList.length);
console.log(retList.toString());
I guess I could have used the swapNodes
function from the lesson and changed it to return list.head
,
but that requires a LinkedList
class (or something like it), and the nodes need to have a .getNextNode()
and .setNextNode( )
.
I think that’s cheating a bit though.
code
/*
Node.prototype.setNextNode = function setNextTo(node) {
this.next = node;
}
Node.prototype.getNextNode = function getNext() {
return this.next;
}
*/
class LinkedList {
constructor(headNode) {
this.head = headNode ? headNode : null;
// define .getNextNode and .setNextNode for nodes in list
let current = this.headNode;
while (current) {
current.setNextNode = function setNext(node) {
this.next = node;
}
current.getNextNode = function getNext() {
return this.next;
}
}
}
*[Symbol.iterator]() {
let current = this.head;
while(current) {
yield current.data;
current = current.next;
}
}
}
function swapNodes(list, data1, data2) {
console.log(`Swapping ${data1} and ${data2}:`);
if (!(list instanceof LinkedList)) {
list = new LinkedList(list);
}
let node1Prev = null;
let node2Prev = null;
let node1 = list.head;
let node2 = list.head;
if (data1 === data2) {
console.log('Elements are the same - no swap to be made');
return list.head;
}
while (node1 !== null) {
if (node1.data === data1) {
break;
}
node1Prev = node1;
node1 = node1.getNextNode();
}
while (node2 !== null) {
if (node2.data === data2) {
break;
}
node2Prev = node2;
node2 = node2.getNextNode();
}
if (node1 === null || node2 === null) {
console.log('Swap not possible - one or more element is not in the list');
return list.head;
}
if (node1Prev === null) {
list.head = node2;
} else {
node1Prev.setNextNode(node2);
}
if (node2Prev === null) {
list.head = node1;
} else {
node2Prev.setNextNode(node1);
}
let temp = node1.getNextNode();
node1.setNextNode(node2.getNextNode());
node2.setNextNode(temp);
return list.head;
}