You are on page 1of 10

Advanced Sorting

Recursive Sorting Algorithms

Problem Statement
z Problem:
• Given a list of N ordinal-type elements, sort the list in
ascending order.

32 35 55 72 89

0 1 2 N-2 N-1

z Algorithms:
• MergeSort
• QuickSort

١
The MergeSort Algorithm
1. Split the unsorted original list into two sub-lists of equal size.

2. Perform MergeSort on each sub-list.


Result: Both sub-lists are now sorted.

3. Merge both sorted sub-lists onto the original list.

Recursive MergeSort in Java


public static <E> void mergeSort (E[ ] data, Comparator c, int first, int n) {
int n1; // Size of the first subarray
int n2; // Size of the second subarray

if (n > 1) {
n1 = n / 2; // Compute size of first subarray
n2 = n – n1; // Compute size of 2nd subarray
mergeSort(data, c, first, n1); // Sort n1 items from data[first]
mergeSort(data, c, first+n1, n2); // Sort n2 items from data[first+n1]
merge(data, c, first, n1, n2); // Merge the two sorted halves.
}
}

٢
MergeSort
The Merging Process
z Two sub-lists are merged into one list that is twice
as long as either of them as follows:
1. Compare the first element from one sub-list with the first
element of the other sub-list, the smallest is appended to
the destination list, and replaced by the next element in its
sub-list.

2. Repeat step 1 until one of the sub-lists is empty, then


append the remaining elements from the other sub-list to
the destination list.

MergeSort
Example:
26 33 35 29 19 12 22 26 33 35 29 19 12 22

Original List
Merge Merge Merge
Recursively subdivide
26 33 35 19 29 12 22
26 33 35 29 19 12 22

Merge Merge

26 33 35 12 19 22 29
26 33 35 29 19 12 22

Merge

26 33 35 29 19 12 22 12 19 22 26 29 33 35 Sorted List

٣
Merge in Java
private static <E> void merge (E[ ] data, Comparator c, int first, int n1, int n2)
{
E[ ] temp; // Array to hold sorted items
int copied = 0; // Number of items copied from data to temp
int copied1 = 0; // Number copied from the first half of data
int copied2 = 0; // Number copied from the second half of data
int i; // Array index to copy from temp back into data

// Allocate memory for the temporary dynamic array.


temp = (E[ ]) new Object [n1+n2];

Merge in Java
// Merge elements, copying from two halves of data to temp array.
while ((copied1 < n1) && (copied2 < n2)) {
if (c.compare(data[first + copied1], data[first + n1 + copied2]) == -1)

// Copy from first half


temp[copied++] = data[first + (copied1++)];

else

// Copy from second half


temp[copied++] = data[first + n1 + (copied2++)];
}

٤
Merge in Java
// Copy any remaining entries in the left and right subarrays.
while (copied1 < n1) temp[copied++] = data[first + (copied1++)];
while (copied2 < n2) temp[copied++] = data[first + n1 + (copied2++)];

// Copy temp to the data array, and release temp's memory.


for (i = 0; i < n1+n2; i++) data[first+i] = temp[i];
temp = null;
}

MergeSort
Discussion

z Suited for sorting linked lists since random access is not


required.

z Also suited for external sorting for the same reason.

z For arrays, we will need a secondary array for the


merging process, which is a serious disadvantage.

٥
MergeSort
Performance Analysis

z The list is broken in half at each stage: O(log n) stages


z Initially, n lists of size 1 each are merged: n steps
z Then n/2 lists of size 2 each are merged: n steps
z Then n/4 lists of size 4, ... : n steps for each stage
z The total cost of mergeSort is O(n log n)

The QuickSort Algorithm


z Select one element of the array; call it the pivot element.
z Determine the final location of the pivot in the (sorted) list; call
that location p.
z Shuffle the elements of the list so that all elements of the list
with values less than or equal to the value of the pivot have
indices less than p. Similarly all elements with values greater
than the pivot’s have indices greater than p.

Example:
<= A[p] A[p] > A[p]

0 1 2 p-1 p p+1 N-2 N-1

٦
QuickSort in Java
<= A[p] A[p] > A[p]

0 1 2 p-1 p p+1 N-2 N-1

public static <E> void quickSort (E[ ] data, Comparator c, int first, int n) {
int p, n1, n2;
if (n > 1) {
p = Partition( data, c, first, n );
n1 = p – first;
n2 = n – n1 – 1;
quickSort( data, c, first, n1 );
quickSort( data, c, p+1, n2 );
}
}

QuickSort
The Partitioning Process
private static <E> int partition (E[ ] A, Comparator c, int first, int n ) {
int right = first + n – 1;
int ls = first;
E pivot = A[first];
for( int i = first+1; i <= right; i++ ) {
if( c.compare(A[i], pivot) <= 0 ) { // Move items smaller than pivot only,
ls++; // to location that would be at left of pivot
swap( A[i], A[ls] ); unexamined
} elements <= pivot elements > pivot elements
}
swap( A[first], A[ls] );

return ls;
} first ls i right
pivot

٧
QuickSort Partitioning Example
if( A[i] <= pivot ) {
Partition( A,0,6 ) ls++;
swap( A[i], A[ls] );}

26 33 35 29 19 12 22 i=4 26 19 35 29 33 12 22

ls ls i
if( A[i] <= pivot ) { if( A[i] <= pivot ) {
ls++; ls++;
swap( A[i], A[ls] );} swap( A[i], A[ls] );}

i=1 26 33 35 29 19 12 22 i=5 26 19 12 29 33 35 22

ls i if( A[i] <= pivot ) { if( A[i] <= pivot ) { ls i


ls++; ls++;
swap( A[i], A[ls] );} swap( A[i], A[ls] );}

i=2 26 33 35 29 19 12 22 i=6 26 19 12 22 33 35 29

ls i if( A[i] <= pivot ) { ls i


ls++;
swap( A[i], A[ls] );} swap( A[first], A[ls] );

i=3 26 33 35 29 19 12 22 22 19 12 26 33 35 29

ls i return ls

QuickSort Example
Initial list ‘A': 26 33 35 29 19 12 22
0 1 2 3 4 5 6
• Select 26 as pivot
QS(A,0,6)
• Shuffle
• Pivot at A[3]
19 12 22 26 33 35 29
0 1 2 3 4 5 6
QS(A,0,2) QS(A,4,6)

• Select 19 as pivot • Select 33 as pivot


• Shuffle • Shuffle
• Pivot at A[1] • Pivot at A[5]

12 19 22 29 33 35
0 1 2 4 5 6

QS(A,0,0) QS (A,2,2) QS(A,4,4) QS(A,6,6)

Done Done Done Done

٨
QuickSort
Performance Analysis
z Worst case: list is broken 0 elements in one partition and n -1 in the
other, that is: n


k =1
k =O
O ( nn22))

z Best case:
• List is broken into two equal halves with n/2 elements each.
• Then broken into four lists with n/4 elements each, etc.
• Total work of n at each stage, with log n stages = O (n log n)

z Average case: assume that the pivot is equally likely to occur at any
position,
n −1
T( n ) = cn + 1
n ∑ (T( k ) + T( n − 1 − k )),
k =0
T( 0 ) = c , T(1) = c

z Solution: O (n log n)

QuickSort
Performance Improvements

1. Choose the pivot as the median of three: A[left], A[right], and


A[(left+right)/2].

2. Keep partitioning until each sub-list has about 10 elements.


Then after QuickSort use insertion sort.
This gives 12% to 20% improvement.

3. Use a non-recursive implementation.

٩
Summary of Sorting Algorithms
Algorithm Time Notes
z in-place
selection-sort O(n2) z slow (good for small inputs)
z in-place
insertion-sort O(n2) z slow (good for small inputs)
O(n log n) z in-place, randomized
quick-sort fastest (good for large inputs)
expected z

z in-place
heap-sort O(n log n) z fast (good for large inputs)

z sequential data access


merge-sort O(n log n) z fast (good for huge inputs)

١٠

You might also like