I am currently trying to swap two nodes in a circular doubly linked list. By current code:
private void swap(Card Card1, Card Card2) {
if (Card1 == head) {
head = Card2;
} else if (Card2 == head) {
head = Card1;
} if (Card1 == tail) {
tail = Card2;
} else if (Card2 == tail) {
tail = Card1;
}
// Swapping Card1 and Card2
Card temp = Card1.next;
Card1.next = Card2.next;
Card2.next = temp;
if (Card1.next != null) {
Card1.next.prev = Card1;
} if (Card2.next != null) {
Card2.next.prev = Card2;
}
temp = Card1.prev;
Card1.prev = Card2.prev;
Card2.prev = temp;
if (Card1.prev != null) {
Card1.prev.next = Card1;
} if (Card2.prev != null) {
Card2.prev.next = Card2;
}
head.prev = tail;
tail.next = head;
}
This code should swap between any two nodes in the linked list but for my application. I am just using it to swap with the next node.
public void moveCard(Card c, int p) {
for (int i = 0; i < p; i++) {
swap(c, c.next);
}
}
Here I am using it to move a card across the list by p positions. Is this correct logic?
I Have been trying to debug this for so long and I cant find where it goes wrong. Any Ideas?
When
Card2isCard1.nextthen the assignmentCard2.next = tempwill makeCard2reference itself. This surely breaks the correct continuation of the swap.The check for
nullreferences could be removed, as in a circular list these should never benull. I didn't see yourNodeclass, but if you initialise those members tonullthere, then change it: make them self references instead, so you can guarantee thatprevandnextare never assignednull.I would take a step back and extract both nodes via a separate
extractfunction, and insert them again with a separateinsertBeforefunction.To avoid havoc, make sure that
Card2.nextis notCard1(so in opposite order). If this is the case repeat the call with the arguments switched, so thatCard1.nextisCard2. But there is still a special case to deal with: if these two cards are the only members of the list, there is no way to prevent thatCard2.nextisCard1, so that case should be dealt with separately: it is an easy case where onlyheadandtailshould reference the other node than they currently do.There shouldn't be much code to set
tail, as there is an invariant:tailis alwayshead.previn a non-empty list. So you can just make that assignment at the end.And I would also use camelCase for your variables, so
card1instead ofCard1.Here is the suggested code: