Java how to sort a Linked List? - java

I am needing to sort a linked list alphabetically. I have a Linked List full of passengers names and need the passengers name to be sorted alphabetically. How would one do this? Anyone have any references or videos?

You can use Collections#sort to sort things alphabetically.

In order to sort Strings alphabetically you will need to use a Collator, like:
LinkedList<String> list = new LinkedList<String>();
list.add("abc");
list.add("Bcd");
list.add("aAb");
Collections.sort(list, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return Collator.getInstance().compare(o1, o2);
}
});
Because if you just call Collections.sort(list) you will have trouble with strings that contain uppercase characters.
For instance in the code I pasted, after the sorting the list will be: [aAb, abc, Bcd] but if you just call Collections.sort(list); you will get: [Bcd, aAb, abc]
Note: When using a Collator you can specify the locale Collator.getInstance(Locale.ENGLISH) this is usually pretty handy.

In java8 you no longer need to use Collections.sort method as LinkedList inherits the method sort from java.util.List, so adapting Fido's answer to Java8:
LinkedList<String>list = new LinkedList<String>();
list.add("abc");
list.add("Bcd");
list.add("aAb");
list.sort( new Comparator<String>(){
#Override
public int compare(String o1,String o2){
return Collator.getInstance().compare(o1,o2);
}
});
References:
http://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html
http://docs.oracle.com/javase/7/docs/api/java/util/List.html

Elegant solution since JAVA 8:
LinkedList<String>list = new LinkedList<String>();
list.add("abc");
list.add("Bcd");
list.add("aAb");
list.sort(String::compareToIgnoreCase);
Another option would be using lambda expressions:
list.sort((o1, o2) -> o1.compareToIgnoreCase(o2));

Here is the example to sort implemented linked list in java without using any standard java libraries.
package SelFrDemo;
class NodeeSort {
Object value;
NodeeSort next;
NodeeSort(Object val) {
value = val;
next = null;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public NodeeSort getNext() {
return next;
}
public void setNext(NodeeSort next) {
this.next = next;
}
}
public class SortLinkList {
NodeeSort head;
int size = 0;
NodeeSort add(Object val) {
// TODO Auto-generated method stub
if (head == null) {
NodeeSort nodee = new NodeeSort(val);
head = nodee;
size++;
return head;
}
NodeeSort temp = head;
while (temp.next != null) {
temp = temp.next;
}
NodeeSort newNode = new NodeeSort(val);
temp.setNext(newNode);
newNode.setNext(null);
size++;
return head;
}
NodeeSort sort(NodeeSort nodeSort) {
for (int i = size - 1; i >= 1; i--) {
NodeeSort finalval = nodeSort;
NodeeSort tempNode = nodeSort;
for (int j = 0; j < i; j++) {
int val1 = (int) nodeSort.value;
NodeeSort nextnode = nodeSort.next;
int val2 = (int) nextnode.value;
if (val1 > val2) {
if (nodeSort.next.next != null) {
NodeeSort CurrentNext = nodeSort.next.next;
nextnode.next = nodeSort;
nextnode.next.next = CurrentNext;
if (j == 0) {
finalval = nextnode;
} else
nodeSort = nextnode;
for (int l = 1; l < j; l++) {
tempNode = tempNode.next;
}
if (j != 0) {
tempNode.next = nextnode;
nodeSort = tempNode;
}
} else if (nodeSort.next.next == null) {
nextnode.next = nodeSort;
nextnode.next.next = null;
for (int l = 1; l < j; l++) {
tempNode = tempNode.next;
}
tempNode.next = nextnode;
nextnode = tempNode;
nodeSort = tempNode;
}
} else
nodeSort = tempNode;
nodeSort = finalval;
tempNode = nodeSort;
for (int k = 0; k <= j && j < i - 1; k++) {
nodeSort = nodeSort.next;
}
}
}
return nodeSort;
}
public static void main(String[] args) {
SortLinkList objsort = new SortLinkList();
NodeeSort nl1 = objsort.add(9);
NodeeSort nl2 = objsort.add(71);
NodeeSort nl3 = objsort.add(6);
NodeeSort nl4 = objsort.add(81);
NodeeSort nl5 = objsort.add(2);
NodeeSort NodeSort = nl5;
NodeeSort finalsort = objsort.sort(NodeSort);
while (finalsort != null) {
System.out.println(finalsort.getValue());
finalsort = finalsort.getNext();
}
}
}

Node mergeSort(Node head) {
if(head == null || head.next == null) {
return head;
}
Node middle = middleElement(head);
Node nextofMiddle = middle.next;
middle.next = null;
Node left = mergeSort(head);
Node right = mergeSort(nextofMiddle);
Node sortdList = merge(left, right);
return sortdList;
}
Node merge(Node left, Node right) {
if(left == null) {
return right;
}
if(right == null) {
return left;
}
Node temp = null;
if(left.data < right.data) {
temp = left;
temp.next = merge(left.next, right);
} else {
temp = right;
temp.next = merge(left, right.next);
}
return temp;
}
Node middleElement(Node head) {
Node slow = head;
Node fast = head;
while (fast != null && fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}

I wouldn't. I would use an ArrayList or a sorted collection with a Comparator. Sorting a LinkedList is about the most inefficient procedure I can think of.

You can do it by Java 8 lambda expression :
LinkedList<String> list=new LinkedList<String>();
list.add("bgh");
list.add("asd");
list.add("new");
//lambda expression
list.sort((a,b)->a.compareTo(b));

If you'd like to know how to sort a linked list without using standard Java libraries, I'd suggest looking at different algorithms yourself. Examples here show how to implement an insertion sort, another StackOverflow post shows a merge sort, and ehow even gives some examples on how to create a custom compare function in case you want to further customize your sort.

Related

Ordering LinkedList <class> [duplicate]

I am needing to sort a linked list alphabetically. I have a Linked List full of passengers names and need the passengers name to be sorted alphabetically. How would one do this? Anyone have any references or videos?
You can use Collections#sort to sort things alphabetically.
In order to sort Strings alphabetically you will need to use a Collator, like:
LinkedList<String> list = new LinkedList<String>();
list.add("abc");
list.add("Bcd");
list.add("aAb");
Collections.sort(list, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return Collator.getInstance().compare(o1, o2);
}
});
Because if you just call Collections.sort(list) you will have trouble with strings that contain uppercase characters.
For instance in the code I pasted, after the sorting the list will be: [aAb, abc, Bcd] but if you just call Collections.sort(list); you will get: [Bcd, aAb, abc]
Note: When using a Collator you can specify the locale Collator.getInstance(Locale.ENGLISH) this is usually pretty handy.
In java8 you no longer need to use Collections.sort method as LinkedList inherits the method sort from java.util.List, so adapting Fido's answer to Java8:
LinkedList<String>list = new LinkedList<String>();
list.add("abc");
list.add("Bcd");
list.add("aAb");
list.sort( new Comparator<String>(){
#Override
public int compare(String o1,String o2){
return Collator.getInstance().compare(o1,o2);
}
});
References:
http://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html
http://docs.oracle.com/javase/7/docs/api/java/util/List.html
Elegant solution since JAVA 8:
LinkedList<String>list = new LinkedList<String>();
list.add("abc");
list.add("Bcd");
list.add("aAb");
list.sort(String::compareToIgnoreCase);
Another option would be using lambda expressions:
list.sort((o1, o2) -> o1.compareToIgnoreCase(o2));
Here is the example to sort implemented linked list in java without using any standard java libraries.
package SelFrDemo;
class NodeeSort {
Object value;
NodeeSort next;
NodeeSort(Object val) {
value = val;
next = null;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public NodeeSort getNext() {
return next;
}
public void setNext(NodeeSort next) {
this.next = next;
}
}
public class SortLinkList {
NodeeSort head;
int size = 0;
NodeeSort add(Object val) {
// TODO Auto-generated method stub
if (head == null) {
NodeeSort nodee = new NodeeSort(val);
head = nodee;
size++;
return head;
}
NodeeSort temp = head;
while (temp.next != null) {
temp = temp.next;
}
NodeeSort newNode = new NodeeSort(val);
temp.setNext(newNode);
newNode.setNext(null);
size++;
return head;
}
NodeeSort sort(NodeeSort nodeSort) {
for (int i = size - 1; i >= 1; i--) {
NodeeSort finalval = nodeSort;
NodeeSort tempNode = nodeSort;
for (int j = 0; j < i; j++) {
int val1 = (int) nodeSort.value;
NodeeSort nextnode = nodeSort.next;
int val2 = (int) nextnode.value;
if (val1 > val2) {
if (nodeSort.next.next != null) {
NodeeSort CurrentNext = nodeSort.next.next;
nextnode.next = nodeSort;
nextnode.next.next = CurrentNext;
if (j == 0) {
finalval = nextnode;
} else
nodeSort = nextnode;
for (int l = 1; l < j; l++) {
tempNode = tempNode.next;
}
if (j != 0) {
tempNode.next = nextnode;
nodeSort = tempNode;
}
} else if (nodeSort.next.next == null) {
nextnode.next = nodeSort;
nextnode.next.next = null;
for (int l = 1; l < j; l++) {
tempNode = tempNode.next;
}
tempNode.next = nextnode;
nextnode = tempNode;
nodeSort = tempNode;
}
} else
nodeSort = tempNode;
nodeSort = finalval;
tempNode = nodeSort;
for (int k = 0; k <= j && j < i - 1; k++) {
nodeSort = nodeSort.next;
}
}
}
return nodeSort;
}
public static void main(String[] args) {
SortLinkList objsort = new SortLinkList();
NodeeSort nl1 = objsort.add(9);
NodeeSort nl2 = objsort.add(71);
NodeeSort nl3 = objsort.add(6);
NodeeSort nl4 = objsort.add(81);
NodeeSort nl5 = objsort.add(2);
NodeeSort NodeSort = nl5;
NodeeSort finalsort = objsort.sort(NodeSort);
while (finalsort != null) {
System.out.println(finalsort.getValue());
finalsort = finalsort.getNext();
}
}
}
Node mergeSort(Node head) {
if(head == null || head.next == null) {
return head;
}
Node middle = middleElement(head);
Node nextofMiddle = middle.next;
middle.next = null;
Node left = mergeSort(head);
Node right = mergeSort(nextofMiddle);
Node sortdList = merge(left, right);
return sortdList;
}
Node merge(Node left, Node right) {
if(left == null) {
return right;
}
if(right == null) {
return left;
}
Node temp = null;
if(left.data < right.data) {
temp = left;
temp.next = merge(left.next, right);
} else {
temp = right;
temp.next = merge(left, right.next);
}
return temp;
}
Node middleElement(Node head) {
Node slow = head;
Node fast = head;
while (fast != null && fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
I wouldn't. I would use an ArrayList or a sorted collection with a Comparator. Sorting a LinkedList is about the most inefficient procedure I can think of.
You can do it by Java 8 lambda expression :
LinkedList<String> list=new LinkedList<String>();
list.add("bgh");
list.add("asd");
list.add("new");
//lambda expression
list.sort((a,b)->a.compareTo(b));
If you'd like to know how to sort a linked list without using standard Java libraries, I'd suggest looking at different algorithms yourself. Examples here show how to implement an insertion sort, another StackOverflow post shows a merge sort, and ehow even gives some examples on how to create a custom compare function in case you want to further customize your sort.

Reverse generic LinkedList by using swap method

public class SimpleLinkedList<E> {
public Node<E> head;
public int size;
public void add(E e) {
++this.size;
if (null == head) {
this.head = new Node();
head.val = e;
} else {
Node<E> newNode = new Node();
newNode.val = e;
newNode.next = head;
this.head = newNode;
}
}
public void swap(E val1, E val2) {
if (val1.equals(val2)) {
return;
}
Node prevX = null, curr1 = head;
while (curr1 != null && !curr1.val.equals(val1)) {
prevX = curr1;
curr1 = curr1.next;
}
Node prevY = null, curr2 = head;
while (curr2 != null && !curr2.val.equals(val2)) {
prevY = curr2;
curr2 = curr2.next;
}
if (curr1 == null || curr2 == null) {
return;
}
if (prevX == null) {
head = curr2;
} else {
prevX.next = curr2;
}
if (prevY == null) {
head = curr1;
} else {
prevY.next = curr1;
}
Node temp = curr1.next;
curr1.next = curr2.next;
curr2.next = temp;
}
public void reverse() {
Node<E> prev = null;
Node<E> current = head;
Node<E> next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
head = prev;
}
public static class Node<E> {
public Node<E> next;
public E val;
}
}
public class SimpleLinkedListTest {
#Test
public void testReverseMethod() {
SimpleLinkedList<Integer> myList = new SimpleLinkedList<>();
for (int i = 0; i < 10; i++) {
myList.add(i);
}
SimpleLinkedList<Integer> expectedList = new SimpleLinkedList<>();
for (int i = 9; i > -1; i--) {
expectedList.add(i);
}
myList.reverse();
assertTrue(AssertCustom.assertSLLEquals(expectedList, myList));
}
}
What would be the most optimal way to reverse generic LinkedList by using the swap method?
before reverse method :
(head=[9])->[8]->[7]->[6]->[5]->[4]->[3]->[2]->[1]->[0]-> null
after reverse() method :
(head=[0])->[1]->[2]->[3]->[4]->[5]->[6]->[7]->[8]->[9]-> null
What you need to do is divide the list in half. If the list size is odd the one in the middle will remain in place. Then swap elements on either side in a mirror like fashion. This should be more efficient than O(n^2)
reverse(){
Node current = this.head;
int half = this.size/2;
int midElement = this.size % 2 == 0 ? 0: half + 1;
Stack<Node<E>> stack = new Stack<Node<E>>();
for(int i = 0; i < this.size; i++){
if (i < = half)
stack.push(current);
else{
if (i == midElement)
continue;
else
swap(stack.pop(), current);
current = current.next;
}
}
swap(Node<E> v, Node<E> v1){
E tmp = v.value;
v.value = v1.value;
v1.value = tmp;
}
This is a little bit of pseudo java. It is missing still the checks for size = 0 or size = 1 when it should return immediately. One for loop. Time Complexity O(n). There is also the need to check when size = 2, swap(...) is to be invoked directly.
Based on the #efekctive 's idea, there a solution. The complexity is a little bit worse than O^2 but no need changes in the swap method, no need in usage of another collection. The code below passes the unit test, however, be careful to use it there could be a bug related to size/2 operation. Hope this help.
public void reverse() {
Node<E> current = head;
SimpleLinkedList<E> firstHalf = new SimpleLinkedList<>();
SimpleLinkedList<E> secondHalf = new SimpleLinkedList<>();
for (int i = 0; i < size; i++) {
if (i >= size / 2) {
firstHalf.add(current.val);
} else {
secondHalf.add(current.val);
}
current = current.next;
}
SimpleLinkedList<E> secondHalfReverse = new SimpleLinkedList<>();
for (int i = 0; i < secondHalf.size(); i++) {
secondHalfReverse.add(secondHalf.get(i));
}
for (int i = 0; i < size / 2; i++) {
if (secondHalfReverse.get(i) == firstHalf.get(i)) {
break;
}
swap(secondHalfReverse.get(i), firstHalf.get(i));
}
}

Reversing K nodes in a Linked List

I have implemented a java code that reverses every k Node in the linked list and here is the code:
public class ReverseALinkedList {
public static void main(String[] args) {
int k = 2;
Node a = new Node(1);
Node b = new Node(2);
Node c = new Node(3);
Node d = new Node(4);
Node e = new Node(5);
Node f = new Node(6);
Node g = new Node(7);
Node h = new Node(8);
a.next = b;
b.next = c;
c.next = d;
d.next = e;
e.next = f;
f.next = g;
g.next = h;
a.printLinkedList();
Node head = reverseKLinkedList(a, k);
head.printLinkedList();
}
private static Node reverseKLinkedList(Node first, int k) {
Node current;
Node temp;
int count = 0;
current = null;
while (first != null && count < k) {
temp = first.next;
first.next = current;
current = first;
first = temp;
++count;
}
if (first != null) {
first.next = reverseKLinkedList(first, k);
}
return current;
}
static class Node {
public Node next;
public int value;
public Node(int value) {
this.value = value;
}
public void printLinkedList() {
Node head = this;
while (head.next != null) {
System.out.print(head.value + "->");
head = head.next;
}
System.out.print(head.value + "->null");
System.out.println();
}
}
}
When I execute the code with the following linked list:
1->2->3->4->5->6->null and k set to 2, I get an output as follows:
2->1->null
The rest of the nodes gets reversed (i.e., 4->3, 6->5), but they are not returned during the recursive call.
Could anybody please let me know how to fix this?
Another way of doing it is to ITERATE every K nodes and store it in a S stack like manner.
Wherein every S is stored in N newList in every K iteration.
private static Node reverseKLinkedList(Node first, int k){
Node newList, temp, current, walk, node;
int count;
node = first;
newList = null;
while(node != null) {
count = 0;
// stack the nodes to current until node is null or count is less than k
current = null;
while(node != null && count < k) {
temp = current;
current = new Node(node.value);
current.next = temp;
node = node.next;
count++;
}
if(newList == null) // if newList is empty then assign the current node
newList = current;
else {
// else traverse against the newList until it reaches
// the last node and then append the current not
walk = newList;
while(walk.next != null) walk = walk.next;
walk.next = current;
}
}
return newList;
}
As you are reversing the first one you are losing the reference to the next Node and therefore you lose the rest of the elements.
To implement this you should use recursion in order to store nodes or a stack(which is basically the same as recursion).
Proceed like this:
Store all the Nodes from the list in a stack.
For each node poped, the next elem is the top of the stack.
Repeat until no more nodes left.
Here is the recursive Java implementation
public static <T> LinearNode<T> reverseAlternateKNodes(LinearNode<T> node, int k) {
int count = 0;
LinearNode<T> curr=node, prev = null, next = null;
//reverse k nodes
while (curr != null && count < k) {
next = curr.next();
curr.next(prev);
prev = curr;
curr = next;
count ++;
}
// head should point to start of next k node
node.next(curr);
// skip nex knodes
count = 0;
while (curr != null && count < k- 1) {
curr = curr.next();
count ++;
}
// do it recursively
if (curr != null) {
curr.next(reverseAlternateKNodes(curr.next(), k));
}
return prev;
}
Here is the unit tests
#Test
public void reverseAlternateKNodes() {
LinearNode<Integer> head = buildLinkedList(1,2,3,4,5,6,7,8,9,10);
head = LinkedListUtil.reverseAlternateKNodes(head, 3);
assertLinkedList(head, 3,2,1,4,5,6,9,8,7,10);
}
public ListNode reverseKGroup(ListNode head, int k) {
ListNode curr = head;
int count = 0;
while(curr!=null && count!=k){
count++;
curr = curr.next;
}
if(count==k){
curr = reverseKGroup(curr,k);
while(count-->0){
ListNode temp = head.next;
head.next = curr;
curr = head;
head = temp;
}
head = curr;
}
return head;
}

Java - Custom Linked List Issue

I have created my own custom Linked List (code is below). Now, I can't understand how to create an array of that Linked list like LinkedList[] l = new LinkedList[10]. Can anyone help me.
class Node {
public int data;
public Node pointer;
}
class LinkedList {
Node first;
int count = 0;
public void addToEnd(int data){
if(first == null){
Node node = new Node();
node.data = data;
node.pointer = null;
first = node;
count = 1;
return;
}
Node next = first;
while(next.pointer != null){
next = (Node)next.pointer;
}
Node newNode = new Node();
newNode.data = data;
newNode.pointer = null;
next.pointer = newNode;
count++;
}
public Node getFirst(){
return first;
}
public Node getLast(){
Node next = first;
while(next.pointer != null)
next = next.pointer;
return next;
}
public int[] get(){
if(count != 0){
int arr[] = new int [count] ;
Node next = first;
int i = 0;
arr[0]= next.data;
while(next.pointer != null){
next = next.pointer;
i++;
arr[i] = next.data;
}
i++;
return arr ;
}
return null ;
}
public int count(){
return count;
}
}
I'm going to guess that your problem is just that when you create an array of objects, like
LinkedList[] lists = new LinkedList[10];
you get an array full of nulls; you need to create objects to store in the array:
for (int i=0; i<lists.length; ++i)
lists[i] = new LinkedList();

What is wrong with this linked list?

The assignment was to write a function to swap 2 nodes in the list. If the function could swap the nodes regardless of the order, a 10% was awarded. I think my implementation is able to swap 2 elements regardless of the order in the list but I still did not received the bonus marks. Is there anything that I am missing?
I was given a generic node class,
public class Node<T> {
public T val;
public Node<T> next;
public Node(T val) {
this.val = val;
this.next = null;
}
}
I was also given an interface defined as below,
public interface SwapList<T> {
public void add(T val);
/**
* Swaps two elements in the list, but only if #param val1 comes BEFORE #param
* val2. Solve the problem regardless of the order, for 10% extra. list: A B
* C -> swap(A,B) will result in the list B A C list: A B C -> swap(B,A)
* will not swap. list: A C C -> swap(A, D) will throw a
* NoSuchElementException list: A B C B -> swap (A, B) will result in the
* list B A C B list: A B C A B B -> swap (A,B) will result in the list B A
* C A B B a list with one or zero elements cannot do a swap
*/
public void swap(T val1, T val2);
public T get(int i);
}
and I have my own implementation of this interface as below,
import java.util.NoSuchElementException;
public class SwapListImpl<T> implements SwapList<T> {
private Node<T> head;
private Node<T> tail;
private int counter;
public SwapListImpl() {
head = null;
tail = null;
counter = 0;
}
#Override
public void add(T val) {
Node<T> node = new Node<T>(val);
if (head == null) {
head = node;
tail = node;
} else {
tail.next = node;
tail = node;
}
counter++;
}
#Override
public void swap(T val1, T val2) {
if (counter < 2 || val1.equals(val2))
return;
Node<T> current = head;
Node<T> currentPrev = null;
Node<T> first = head;
Node<T> firstPrev = null;
Node<T> firstNext = first.next;
Node<T> second = head;
Node<T> secondPrev = null;
Node<T> secondNext = second.next;
boolean foundFirst = false;
boolean foundSecond = false;
boolean inOrder = false;
while (current != null) {
if (!foundFirst && current.val.equals(val1)) {
firstPrev = currentPrev;
first = current;
firstNext = current.next;
if (!foundSecond)
inOrder = true;
foundFirst = true;
}
if (!foundSecond && current.val.equals(val2)) {
secondPrev = currentPrev;
second = current;
secondNext = current.next;
if (foundFirst)
inOrder = true;
foundSecond = true;
}
if (foundFirst && foundSecond) {
if (!inOrder) {
Node<T> temp = first;
first = second;
second = temp;
temp = firstPrev;
firstPrev = secondPrev;
secondPrev = temp;
temp = firstNext;
firstNext = secondNext;
secondNext = temp;
}
if (firstPrev == null) {
head = second;
if (first == secondPrev) {
second.next = first;
first.next = secondNext;
} else {
second.next = firstNext;
secondPrev.next = first;
first.next = secondNext;
}
} else {
firstPrev.next = second;
first.next = secondNext;
if (first == secondPrev) {
second.next = first;
} else {
second.next = firstNext;
secondPrev.next = first;
}
}
break;
}
currentPrev = current;
current = current.next;
}
if (!foundFirst || !foundSecond) {
throw new NoSuchElementException();
}
}
#Override
public T get(int i) {
if (i < counter) {
Node<T> node = head;
for (int n = 0; n < i; n++) {
node = node.next;
}
return node.val;
} else {
throw new IndexOutOfBoundsException();
}
}
}
I think the problem is the swap itself: you forgot to set the tail.
Here is a small test for exactly that problem:
#Test
public void test() {
SwapListImpl<String> list = new SwapListImpl<String>();
list.add("A");
list.add("B");
list.add("C");
list.swap("A", "C");
assertEquals("C", list.get(0));
assertEquals("C", list.getHead().val);
assertEquals("B", list.get(1));
assertEquals("A", list.get(2));
assertEquals("A", list.getTail().val);
list.add("D");
assertEquals("C", list.get(0));
assertEquals("C", list.getHead().val);
assertEquals("B", list.get(1));
assertEquals("A", list.get(2));
assertEquals("D", list.get(3));
assertEquals("D", list.getTail().val);
list.swap("A", "C");
assertEquals("A", list.get(0));
assertEquals("A", list.getHead().val);
assertEquals("B", list.get(1));
assertEquals("C", list.get(2));
assertEquals("D", list.get(3));
assertEquals("D", list.getTail().val);
list.swap("C", "B");
assertEquals("A", list.get(0));
assertEquals("A", list.getHead().val);
assertEquals("C", list.get(1));
assertEquals("B", list.get(2));
assertEquals("D", list.get(3));
assertEquals("D", list.getTail().val);
}
You see I added two methods to the list, for getting the head and tail, but that's not important - the test would even fail without the explicit test for head and tail. The extra methods for the list are really simple:
public Node<T> getTail() {
return this.tail;
}
public Node<T> getHead() {
return this.head;
}
The problem of not setting tail occurs when swapping the last element of the list and then adding another element.
Here is a fixed version of the actual swap:
if (foundFirst && foundSecond) {
if (second == this.tail) {
this.tail = first;
} else if (first == this.tail) {
this.tail = second;
}
if (first == this.head) {
this.head = second;
} else if (second == this.head) {
this.head = first;
}
if (firstPrev == second) {
first.next = second;
} else {
if (firstPrev != null) {
firstPrev.next = second;
}
first.next = secondNext;
}
if (secondPrev == first) {
second.next = first;
} else {
if (secondPrev != first && secondPrev != null) {
secondPrev.next = first;
}
second.next = firstNext;
}
break;
}
You see I didn't add lines to your code - instead I wrote the code in another way. I think it's more readable, but you also can try just to set the tail in the correct way. But it was too complex for me, so I reduced the complexity of that code - that's the reason why I rewrote it.
I would suggest, that you use first and second for the first/second occurence and not for the first/second argument. I think that would improve the readability of the method. But that's another point ;-)
Hope that helps - so the order IMHO is not the problem, but the tail.

Categories

Resources