JavaScript Challenge - Swap Elements in a Linked List

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 (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 (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 (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