0

I am making a project right now to practice double linked lists and I have been working on a method in my double linked lists class which switches node locations. It works fine when trying to switch non adjacent nodes but when trying to switch adjacent nodes the error occurs for example.

If the starting list is:

  1. Carrot
  2. Candy
  3. Watermelon
  4. Bread

The output will be

  1. Carrot
  2. Watermelon
  3. Watermelon
  4. Bread

Im trying to figure out the error but my knowledge is lacking there, Any help would be great I appreciate it!

I tried creating a temp node to hold the original prev and next for the nodes, but that didnt work. I tried if statements which checked if the prev and next were equal and that didnt work.

Here is my code

public void switchNodes(int firstSpace, int secondSpace){
    
    //If statement which checks isEmpty(), and if firstSpace and secondSpace is less than 0.
    if(isEmpty()|| firstSpace < 0 || secondSpace < 0){
        System.out.println("List is empty or one of spaces is entered does not have anything in it.");//If any of the previous if scenarios is met, prints a message telling the user that.
    }
    else{
    Node<E> firstN = current(firstSpace); //Creates a node firstN by calling the current method and using the imported firstSpace int.
    Node<E> secondN = current(secondSpace); //Creates a node secondN by calling the current method and using the imported secondSpace int.
    
    switchSpace(firstN, secondN);//Calls the switchSpace method with nodes firstN and secondN.

    }  
}

  /**
   *Private method which takes in two nodes and switches their positions on the list.
   * Done by creating two nodes with the information imported from the switchNodes method.
   * The created nodes contain the same element and the swapped prev and next.
   * The nodes around the swapped nodes are then accessed and replaced to the swapped nodes address.
   */
  private void switchSpace(Node<E> firstSwitch, Node<E> secondSwitch){
    
    //Creates switchedFirst node to contain the element of the imported firstSwitch node and the addresses of the secondSwitch node.
    Node<E> switchedFirst = new Node<E>(firstSwitch.getElement(), secondSwitch.getPrev(), secondSwitch.getNext());
    //Creates switchedSecond node to contain the element of the imported secondSwitch node and the addresses of the firstSwitch node.
    Node<E> switchedSecond = new Node<E>(secondSwitch.getElement(), firstSwitch.getPrev(), firstSwitch.getNext());
    
    switchedFirst.getNext().setPrev(switchedFirst);//The node after the switchedFirst nodes new position is accessed and the prev address is set to switchedFirst.
    switchedFirst.getPrev().setNext(switchedFirst);//The node before the switchedFirst nodes new position is accessed and the next address is set to switchedFirst.

    switchedSecond.getNext().setPrev(switchedSecond);//The node after the switchedSecond nodes new position is accessed and the prev address is set to switchedSecond.
    switchedSecond.getPrev().setNext(switchedSecond);//The node before the switchedSecond nodes new position is accessed and the next address is set to switchedSecond.
    
  
}
0

1 Answer 1

0

Your problem comes from the way you are creating the updated nodes. Lets say you have this list (Sorry for the bad drawing):

a <--> b <--> c <--> d

and you want to switch b and c.

Your are creating the updated b(ub) by setting its prev and next to c's prev and next respectively. Similarly, the updated c(uc) is created by setting its prev and next to b's prev and next respectively.

        <----ub---->
       /            \
a <--> b <--> c <--> d
\             /   
 <------uc--->       

Now you are trying to link the old prev and next to the new ones.

        <---ub<---->
       /            \
a <--- b <--> c --> d
\             /   
 <--->uc----->       

Now, if you traverse it, you will get

a, uc, c, d

This problem only occurs if the prev/next points to any node that is to be replaced. To solve this, you need to replace the old nodes with the updated nodes if any next/prev points to it. Here, is the updated code

    private void switchSpace(Node<E> firstSwitch, Node<E> secondSwitch){
        // Creates updatedFirst node to contain the element of the second node
        // Don't set the prev and next yet
        Node<E> updatedFirst = new Node<E>(secondSwitch.getElement(), null, null);
        // Creates updatedSecond node to contain the element of the First node
        // Don't set the prev and next yet
        Node<E> updatedSecond = new Node<E>(firstSwitch.getElement(), null, null);

        // Find the prev and next of the old nodes. If any prev/next point to any old element that is
        // about to be replaced, use the new one in its place
        Node<E> prev1 = firstSwitch.getPrev() == secondSwitch ? updatedSecond : firstSwitch.getPrev();
        Node<E> next1 = firstSwitch.getNext() == secondSwitch ? updatedSecond : firstSwitch.getNext();
        Node<E> prev2 = secondSwitch.getPrev() == firstSwitch ? updatedFirst : secondSwitch.getPrev();
        Node<E> next2 = secondSwitch.getNext() == firstSwitch ? updatedFirst : secondSwitch.getNext();

        // Set the prev and next of the updated nodes
        if (next2 != null) {
            next2.setPrev(updatedSecond);
            updatedSecond.setNext(next2);
        }

        if (prev2 != null) {
            prev2.setNext(updatedSecond);
            updatedSecond.setPrev(prev2);
        }

        if (next1 != null) {
            next1.setPrev(updatedFirst);
            updatedFirst.setNext(next1);
        }

        if (prev1 != null) {
            prev1.setNext(updatedFirst);
            updatedFirst.setPrev(prev1);
        }

        // Check if the head needs to be updated
//        if (head == firstSwitch) {
//            head = updatedFirst;
//        } else if (head == secondSwitch) {
//            head = updatedSecond;
//        }
    }

Also, you will have to update the head of the list if the first node gets replaced. The last four commented out lines do that.

The easiset way to swap two nodes would be to swap just the elements. In that way you don't need to bother with other links.

    private void switchSpace(Node<E> firstSwitch, Node<E> secondSwitch){
        // Swap the elements
        E temp = firstSwitch.getElement();
        firstSwitch.setElement(secondSwitch.getElement());
        secondSwitch.setElement(temp);
    }

Hope this helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Woah that helped a lot! Thank you for the help!. The uc and ub stuff confused me a bit if theres a better way of understanding that please let me know!. But I tried the easiest way and it worked perfectly! Do you have any tips for a newer coder on how to thing more simply than grandly when it comes to examples like the easiset way to swap because I feel like I find myself trying to make something much more grand than it needs to be. Truly though thank you again! When im less tired im gonna re read what you said about my original code and how it works If I grasp it better Ill let you know
@TylerDr16 I usually like to draw on a piece of parer/board while working with LinkedList or Graph. It helps a lot to visualize what I am trying to do. You can also hand simulate your algorithm to figure out how it would work. For the uc`ub` bit you can try this approach. Don't worry about the grandness. I have been there. Keep learning, keep practicing.
Got it thank you so much!! I thought I actually needed to fully switch the nodes itself didn't think I could actually just swap the elements its self. Life changing concept. YOU ARE THE GOAT! Ive been doing more visualization and it definetly helps a lot! Much more practice I need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.