Here is the source of the question: GitHub
Given a singly linked list, swap the list items in pairs (reconnect the pointers, not simply swap the values). For example:
Before: A->B->C->D
After: B->A->D->C
See the method reversePairs
.
Node
class Node {
private Node next;
private int data;
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setNext(Node next) {
this.next = next;
}
public Node getNext() {
return next;
}
@Override
public String toString() {
return Integer.toString(data);
}
}
SinglyLinkedList
public class SinglyLinkedList {
private Node mFirst;
private Node mLast;
public SinglyLinkedList(Node first) {
this.mFirst = first;
this.mLast = first;
}
public SinglyLinkedList(int []array) {
if (array == null || array.length == 0) {
throw new IllegalArgumentException();
}
this.mFirst = new Node(array[0]);
this.mLast = this.mFirst;
for (int i = 1; i < array.length; i++) {
addLast(new Node(array[i]));
}
}
public void addLast(Node node) {
mLast.setNext(node);
mLast = node;
}
public Node getFirst() {
return mFirst;
}
public Node getLast() {
return mLast;
}
public void print() {
Node current = mFirst;
System.out.print("[");
while (current != null) {
System.out.print(current);
current = current.getNext();
if (current != null) {
System.out.print(", ");
}
}
System.out.print("]");
System.out.println();
}
public void reversePairs() {
Node prev = mFirst;
Node curr = prev.getNext();
Node old = null;
while (curr != null) {
Node next = curr.getNext();
curr.setNext(prev);
prev.setNext(null);
if (prev == mFirst) {
mFirst = curr;
}
if (old != null) {
old.setNext(curr);
}
old = prev;
prev = next;
if (prev != null) {
curr = prev.getNext();
if (curr == null) {
old.setNext(prev);
mLast = prev;
}
} else {
mLast = old;
break;
}
}
}
}
Testing:
package com.reversell;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class SinglyLinkedListTest {
private int[] single = new int[] {
12
};
private int[] twoElems = new int[] {
12, 34
};
private int[] twoElemsReversedPairs = new int[] {
34, 12
};
private int[] threeElems = new int[] {
12, 34, 78
};
private int[] threeElemsReversedPairs = new int[] {
34, 12, 78
};
private int[] evenElems = new int[] {
12, 34, 78, 124
};
private int[] evenElemsReversedPairs = new int[] {
34, 12, 124, 78
};
private int[] oddElems = new int[] {
12, 34, 78, 45, 90
};
private int[] oddElemsReversedPairs = new int[] {
34, 12, 45, 78, 90
};
@Test
public void test() {
assertEquals(true, doReverse(new SinglyLinkedList(single), single, single));
assertEquals(true, doReverse(new SinglyLinkedList(twoElems), twoElems, twoElemsReversedPairs));
assertEquals(true, doReverse(new SinglyLinkedList(threeElems), threeElems, threeElemsReversedPairs));
assertEquals(true, doReverse(new SinglyLinkedList(oddElems), oddElems, oddElemsReversedPairs));
assertEquals(true, doReverse(new SinglyLinkedList(evenElems), evenElems, evenElemsReversedPairs));
}
private boolean isFirstCorrect(SinglyLinkedList linkedList, int value) {
return linkedList.getFirst().getData() == value;
}
private boolean isLastCorrect(SinglyLinkedList linkedList, int value) {
return linkedList.getLast().getData() == value;
}
private boolean doReverse(SinglyLinkedList list, int[] origArray, int[] reversedArray) {
boolean checkOrig = isListCorect(list, origArray);
if (!checkOrig) {
return false;
}
list.reversePairs();
return isFirstCorrect(list, reversedArray[0]) && isLastCorrect(list,
reversedArray[reversedArray.length - 1]) && isListCorect(list, reversedArray);
}
private boolean isListCorect(SinglyLinkedList list, int[] array) {
Node curr = list.getFirst();
int arrayIndex = 0;
while (curr != null) {
if (array[arrayIndex] != curr.getData()) {
return false;
}
curr = curr.getNext();
arrayIndex++;
}
return true;
}
}