Search code examples
javadoubly-linked-listcircular-list

Triple-cut of a circular doubly linked list, Java


Given a circular doubly linked list deck (possesing field head) which has nodes card (possessing fields next and prev), I want to perform a "triple-cut" on the deck, which is defined as picking two cards in the deck and the elements before the first card are replaced with the elements after the second card. The method has to be O(1).

My idea is to generate two new circular doubly linked lists deck1 and deck2 and store the left part of the deck and the right part in them, respectively.I made the following picture to better explain what I am trying to achieve:

enter image description here

Here follows my coding attempt, the issue arises when trying to slice 'this' deck, and recombining the sliced deck with the new 2 decks in appropriate order.

public void tripleCut(Card firstCard, Card secondCard) {
    
    
    // inputs : firstCard = 3H 
    // inputs : secondCard = 2C
    
        // this deck : AC 2D 3H 4D AD 4H 4C AH 2C RJ 3C BJ 3D 2H 

    // deck 3
    Deck d3 = new Deck();
    d3.head = secondCard.next;
    secondCard = d3.head.prev;
    d3.head.prev = this.head.prev;
    
        // d3.head = RJ 
        // d3.head.prev = 2H
    
    //deck 1
    Deck d1 = new Deck();
    d1.head = this.head;
    d1.head.prev = firstCard.prev;

        // d1.head = AC 
        // d1.head.prev = 2D
    
    // Slicing the two decks from 'this' deck

    this.head.prev = secondCard;
    secondCard.next = this.head;
    
    this.head = firstCard;
    firstCard.prev = secondCard;
    this.head.prev = secondCard;
    secondCard.next= this.head;
    
    head.prev.next=d1.head;
    head.prev = d1.head.prev;

}

When I try to recombine the decks I get nonsense, suggesting that what I did above is incorrect. How would you guys approach this problem? Even pseudo-code would hewlp, I have been stuck on this for far to long I am really lost.


Solution

  • Clarify on cases

    1. left = null and/or right = null
    2. left == right == head
    3. will left be always before right

    Basic idea

    Cut

    Assumes head is accessible and left/right order is maintained

    1. Three parameters - head, left, right
    2. derive tail = head.prev
    3. backup beforeLeft = left.prev and afterRight = right.next
    4. cut tail, head cycle (tail.next = head.prev = null)
    5. cut left.prev = right.next = null, beforeLeft.next = null, afterRight.prev = null

    Join

    1. Six parameters - head, tail, left, right, beforeLeft, afterRight
    2. head will move after right (right.next = head, head.prev = right)
    3. tail will move before left (left.prev = tail, tail.next = left)
    4. set new head and tail (head = afterRight, tail = beforeLeft)
    5. join new head and tail (head.prev = tail, tail.next = head)

    I have not tested this and its one of the possible approach.