Skip to content

Commit

Permalink
Merge sort on linked list
Browse files Browse the repository at this point in the history
  • Loading branch information
onkar committed Sep 6, 2014
1 parent af95b86 commit 5e207ff
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
67 changes: 67 additions & 0 deletions Sorting/src/main/LinkedListMergeSort.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main;

public class LinkedListMergeSort {

public ListNode mergeSortList(ListNode head) {
// Base condition of the recursion. If the list is empty or if only one element is present,
// return the element
if (head == null || head.next == null) {
return head;
}

// Use slow and fast pointer method. Slow points to the first element and fast points to the
// second element. Then onwards, fast is incremented twice for each increment in slow pointer.
// This way, we can split the linked list in 2 halves.
ListNode slow = head;
ListNode fast = head.next;
while (fast != null) {
fast = fast.next;
if (fast != null) {
slow = slow.next;
fast = fast.next;
}
}

// Create two lists, slow becomes the head of first half and fast becomes the head of the second
// half. Both halves are passed to the recursion.
fast = slow.next;
slow.next = null;
slow = head;
ListNode h1 = mergeSortList(slow);
ListNode h2 = mergeSortList(fast);

// Merge the result of sorted lists
ListNode result = merge(h1, h2);
return result;
}

private ListNode merge(ListNode h1, ListNode h2) {
ListNode p1 = h1;
ListNode p2 = h2;
// Fake head is the previous node of head of the merged linked list. This trick is used when you
// don't want to allocate separate memory for storing the merging result.
ListNode fakeHead = new ListNode(0);
ListNode p = fakeHead;
while (p1 != null && p2 != null) {
if (p1.value <= p2.value) {
p.next = p1;
p1 = p1.next;
} else {
p.next = p2;
p2 = p2.next;
}
p = p.next;
}
if (p1 != null) {
// Attach remaining elements to the result
p.next = p1;
}
if (p2 != null) {
// Attach remaining elements to the result
p.next = p2;
}
// Return fake head's next element which is the actual head of the merged linked list.
return fakeHead.next;
}

}
11 changes: 11 additions & 0 deletions Sorting/src/main/ListNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main;

public class ListNode {
public final int value;
public ListNode next;

public ListNode(int value) {
this.value = value;
this.next = null;
}
}
36 changes: 36 additions & 0 deletions Sorting/src/test/LinkedListTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package test;

import static org.junit.Assert.fail;
import main.LinkedListMergeSort;
import main.ListNode;

import org.junit.Before;
import org.junit.Test;

public class LinkedListTest {
private ListNode n1;

@Before
public void setup() throws Exception {
n1 = new ListNode(15);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(11);

n1.next = n2;
n2.next = n3;
n3.next = null;
}

@Test
public void testLinkedListMergeSort() throws Exception {
LinkedListMergeSort llm = new LinkedListMergeSort();
ListNode result = llm.mergeSortList(n1);
ListNode temp = result;
while (temp.next != null) {
if (temp.value > temp.next.value) {
fail("LinkedList is not sorted...");
}
temp = temp.next;
}
}
}

0 comments on commit 5e207ff

Please sign in to comment.