You are on page 1of 79

Chapter 8

Sorting Algorithms
Part II
Analysis of Merge Sort

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-2
Merge Sort Definition

• erge sort or mergesort is an O(NlogN)


sorting algorithm.
• It is an example of the divide and conquer
algorithmic paradigm.
• It is a comparison sort.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-3
Rationale for Divide and Conquer

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-4
Merge Sort Algorithm
mergeSort
Cut the array in half
Sort the left half
Sort the right half
Merge the two sorted halves into one sorted array

Because mergeSort is itself a sorting algorithm, we might as well


use it to sort the two halves.

We can make mergeSort a recursive method and let it call itself


to sort each of the two subarrays:

mergeSort—Recursive
Cut the array in half
mergeSort the left half
mergeSort the right half
Merge the two sorted halves into one sorted array
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-5
Merge Sort Summary
Method mergeSort(first, last)
Definition: Sorts the array elements in ascending order.

Size: last - first + 1

Base Case: If size less than 2, do nothing.

General Case: Cut the array in half.


mergeSort the left half.
mergeSort the right half.
Merge the sorted halves into one sorted array.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-6
Strategy
for
Merging
Two
Sorted
Arrays

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-7
Merge Sort Algorithm

• Conceptually, a merge sort works as follows:


– Divide the unsorted list into two sublists of about
half the size
– Divide each of the two sublists recursively until
we have list sizes of length 1, in which case the
list itself is returned
– Merge the two sublists back into one sorted list.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-8
Merge Sort Algorithm (2)
• Mergesort incorporates two main ideas to
improve its runtime:
– A small list will take fewer steps to sort than a
large list.
– Fewer steps are required to construct a sorted
list from two sorted lists than two unsorted lists.
– For example, you only have to traverse each list
once if they're already sorted.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-9
Merge Sort (2)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-10
Merge Sort (3)

• It involves three steps:


– If the number of items to sort is 0 or 1, return.
– Recursively sort the first and second halves
separately
– Merge the two sorted halves into a sorted
group.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-11
Linear-time Merging
of Sorted Arrays

• The basic merge algorithm takes two input


arrays, A and B, an output array, C, and
three counters, Am, Bar, and Car, which are
initially set to the beginning of their
respective arrays.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-12
Linear-time Merging
of Sorted Arrays (2)
• The smaller of A [Actr] and B [Bctr] is
copied to the next entry in C, and the
appropriate counters are advanced.
• When either input array is exhausted, the
rest of the other array is copied to C.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-13
Linear-time Merging
of Sorted Arrays (3)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-14
Linear-time Merging
of Sorted Arrays (4)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-15
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-16
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-17
Mergesort: Example 1
public class Mergesort{
public static void mergesort (int[ ] data, int first, int n) {
int n1; // Size of the first half of the array
int n2; // Size of the second half of the array
if (n > 1) {
n1 = n / 2;
n2 = n - n1;
mergesort (data, first, n1);
mergesort (data, first + n1, n2);
merge (data, first, n1, n2);
}
}
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-18
public static void merge(int[ ] data, int first, int n1, int n2) {
int[ ] temp = new int[n1+n2];
int copied = 0;
int copied1 = 0;
int copied2 = 0; int i;
while ((copied1 < n1) && (copied2 < n2)) {
if (data[first + copied1] < data[first + n1 + copied2])
temp[copied++] = data[first + (copied1++)];
else
temp[copied++] = data[first + n1 + (copied2++)];
}
while (copied1 < n1)
temp[copied++] = data[first + (copied1++)];
while (copied2 < n2)
temp[copied++] = data[first + n1 + (copied2++)];
for (i = 0; i < n1+n2; i++)
data[first + i] = temp[i]; Mergesort:
}
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
Example 1 (2) 8-19
Mergesort: Example 1 (3)
Output
public static void main (String [] args) { 0
1
int arr[]= {45,23,96,0,23,6,1,1,1,34,34,2,78,1}; 1
mergesort(arr,0,14); 1
1
for (int i=0;i<14;i++) 2
System.out.println (arr[i]); 6
} 23
23
} 34
34
45
78
96
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-20
class DArray {
private long[] theArray;
private int nElems;

Merge Sort: Example 2


public DArray(int max){
theArray = new long[max];
nElems = 0;
}
public void insert(long value) {
theArray[nElems] = value;
nElems++;
}
public void display() {
for(int j=0; j<nElems; j++)
System.out.print(theArray[j] + " ");
System.out.println("");
}
public void mergeSort() {
long[] workSpace = new long[nElems];
recMergeSort(workSpace, 0, nElems-1);
}

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-21
Merge Sort: Example 2 (2)

private void recMergeSort(long[] workSpace, int lowerBound,int


upperBound) {
if(lowerBound == upperBound)
return;
else {
int mid = (lowerBound+upperBound) / 2;
recMergeSort(workSpace, lowerBound, mid);
recMergeSort(workSpace, mid+1, upperBound);
merge(workSpace, lowerBound, mid+1, upperBound);
}
}

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-22
private void merge(long[] workSpace, int lowPtr, int highPtr, int upperBound) {

Merge Sort: Example 2 (3)


int j = 0;
int lowerBound = lowPtr;
int mid = highPtr-1;
int n = upperBound-lowerBound+1;
while(lowPtr <= mid && highPtr <= upperBound)
if( theArray[lowPtr] < theArray[highPtr] )
workSpace[j++] = theArray[lowPtr++];
else
workSpace[j++] = theArray[highPtr++];
while(lowPtr <= mid)
workSpace[j++] = theArray[lowPtr++];
while(highPtr <= upperBound)
workSpace[j++] = theArray[highPtr++];
for(j=0; j<n; j++)
theArray[lowerBound+j] = workSpace[j];
}
}

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-23
class MergeSortApp {
public static void main(String[] args) {

Merge Sort: Example 2 (4)


int maxSize = 100;
DArray arr;
arr = new DArray(maxSize);
arr.insert(64);
arr.insert(21);
arr.insert(33);
arr.insert(70);
arr.insert(12);
arr.insert(85);
arr.insert(44);
arr.insert(3);
arr.insert(99);
arr.insert(0);
arr.insert(108);
arr.insert(36);
arr.display();
arr.mergeSort();
arr.display();
}
}Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-24
Homework #1

• Write and explain Java program that


implements Mergesort using recursion.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-25
Analysis of Quick Sort

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-26
Quick Sort Algorithm

• This algorithm is a fast divide-and-conquer


algorithm.
• Average running time is O(N logN).
• It speed is mainly due to a very tight and
highly optimized inner loop.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-27
Quick Sort Algorithm (2)
• The basic algorithm Quick sort (S) consists of the four
steps:
– If the number of elements in S is 0 or 1, then return
– Pick any element v in S. It is called the pivot.
– Partition S – {v} into two disjoint groups:
L = {x in S–{v} | x<=v} and
R = {x in S–{v} | x>= v}.
– Return the result of Quicksort (L) followed by v followed by
Quicksort (R).

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-28
Quick Sort Algorithm (3)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-29
Quick Sort Algorithm (3)

• In the partition step, every element in S,


except for the pivot, is placed in either L
(which stands for the left part of the array)
or R (which stands for the right-hand part of
the array).
• Elements that are smaller than the pivot go
to L and the elements larger than the pivot
go to R.
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-30
Quick Sort Algorithm (3)
• The pivot is chosen (by chance) to be 65.
• The remaining elements in the set are
partitioned into two smaller subsets.
• Each group is then sorted recursively.
• The sorted arrangement of the entire group
is then trivially obtained.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-31
Quick Sort Algorithm (4)

• After the partitioning step, the pivot would


wind up in some array cell p.
• The recursive calls would then be on the
parts from low to (p-1) and then (p+1) to
high.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-32
Analysis of Quicksort
Best case
• The best case for quicksort is that the pivot
partitions the set into two equally sized
subsets and that this partitioning happens at
each stage of the recursion.
• We then have two half-sized recursive calls
plus linear overhead, which matches the
performance of mergesort. The running
time for this case is O(N log N) .

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-33
Analysis of Quicksort (2)
Worst case
• In each step of the recursion, the pivot
happens to be the smallest element.
• Then the set of small elements L will be
empty, and the set of large elements R will
have all the elements except the pivot.
• The running time is now O(N2).

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-34
Picking the Pivot: First Element
• This selection is acceptable if the input is
random, but if the input has been presorted
or is in reverse order, the pivot provides a
poor partition because it is an extreme
element.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-35
Picking the Pivot:
Pivot is the Middle Element
• When the input has already been sorted, this
selection gives the perfect pivot in each
recursive call.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-36
Picking the Pivot:
Median-of-three Partitioning
• Median-of-three partitioning is an attempt
to pick a better than average pivot.
• In median-of-three partitioning, the median
of the first, middle, and last elements is
used as the pivot.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-37
Partitioning Strategy
• The first step in the partitioning algorithm is
to get the pivot element out of the way by
swapping it with the last element.
• Assume that all the elements are distinct
and leave for later what to do in the
presence of duplicates.
• As a limiting case, our algorithm must work
properly when all the elements are
identical.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-38
Partitioning Strategy (2)

pivot

Picking the Pivot:


Pivot is the Middle Element

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-39
Partitioning Strategy
Step 1

• Swap the Pivot with the element at the end.


• Get the pivot element out of the way by
swapping it with the last element.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-40
Partitioning Strategy
Step 1 (2)
pivot

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-41
Partitioning Strategy
Step 1 (3)

• The pivot element is shown in the darkest


shade at the end of the array.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-42
Partitioning Strategy
Step 2
• Run i from left to right and j from right to left.
• When i encounters a large element, i stops.
When j encounters a small element, j stops.
• If i and j have not crossed, swap their items
and continue. Otherwise, stop this loop.
j
i

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-43
Partitioning Strategy
Step 1 (2)

j
i

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-44
Partitioning Strategy
Step 3

• Swap the element in position i with the pivot.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-45
Partitioning Strategy
Step 3 (2)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-46
Partitioning Strategy
Step 3 (3)

j
i

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-47
Partitioning Strategy
Step 3 (4)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-48
Partitioning Strategy
Step 3 (5)
i
positio
n

j i

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-49
Partitioning Strategy
Step 3 (6)

i
positio
n

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-50
Special Case:
Keys Equal to the Pivot

• Counters i and j must stop when they


encounter an item equal to the pivot.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-51
Median-of-three Partitioning
• Median-of-three partitioning requires that
we find the median of the first, middle, and
last elements.
• Then sort them in the array.
• Note the resulting shading: The element that
winds up in the first position is guaranteed
to be smaller than (or equal to) the pivot,
and the element in the last position is
guaranteed to be larger than (or equal to)
the pivot. This outcome tells us four things.
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-52
Median-of-three Partitioning (2)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-53
Median-of-three Partitioning (3)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-54
Median-of-three Partitioning (4)

• Do not swap the pivot with the element in


the last position.
• Instead, swap it with the element in the
next-to-last position.
• Start i at low+1 and j at high-2.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-55
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-56
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-57
Picking the
Pivot: First
Element

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-58
Quicksort Example

public static <AnyType extends Comparable<? super AnyType>>


void quicksort( AnyType [ ] a ) {
quicksort( a, 0, a.length - 1 );
}
private static final int CUTOFF = 10;
public static final <AnyType>
void swapReferences( AnyType [ ] a, int index1, int index2 ) {
AnyType tmp = a[ index1 ];
a[ index1 ] = a[ index2 ];
a[ index2 ] = tmp;
}

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-59
private static <AnyType extends Comparable<? super AnyType>>
void quicksort( AnyType [ ] a, int low, int high ) {
if( low + CUTOFF > high )

Quicksort Example (2)


insertionSort( a, low, high );
else {
int middle = ( low + high ) / 2;
if( a[ middle ].compareTo( a[ low ] ) < 0 )
swapReferences( a, low, middle );
if( a[ high ].compareTo( a[ low ] ) < 0 )
swapReferences( a, low, high );
if( a[ high ].compareTo( a[ middle ] ) < 0 )
swapReferences( a, middle, high );
swapReferences( a, middle, high - 1 );
AnyType pivot = a[ high - 1 ];
int i, j;

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-60
Quicksort Example (3)
for(i = low, j = high - 1; ;){
while( a[ ++i ].compareTo( pivot ) < 0 )
;
while( pivot.compareTo( a[ --j ] ) < 0 )
;
if( i >= j )
break;
swapReferences( a, i, j );
}

swapReferences( a, i, high - 1 );
quicksort( a, low, i - 1 );
quicksort( a, i + 1, high );
}
}

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-61
Homework #2

• Create a full Java program that implements


Quicksort.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-62
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-63
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-64
Analysis of Shell Sort

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-65
Shell Sort

• The first algorithm to improve on the insertion


sort substantially was Shellsort.
• It is not the fastest algorithm but it is a
subquadratic algorithm whose code is only
slightly longer than the insertion sort, making
it the simplest of the faster algorithms.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-66
Shell Sort (2)

• Shell's idea was to avoid the large amount


of data movement, first by comparing
elements that were far apart and then by
comparing elements that are less far apart,
and so on, gradually shrinking toward the
basic insertion.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-67
Shell Sort (3)
• Shellsort uses a sequence h1 h2, ..., ht called
the increment sequence.
• Any increment sequence will do as long as
h1 = 1, but some choices are better than
others.
• After a phase, using some increment h K, we
have a[i] ≤ a[i+ hK] for every i where i + hK
is a valid index.
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-68
Shell Sort (4)

• All elements spaced apart are sorted.


• The array is then said to be hK-sorted.
• For example, next slide shows an array after
several phases of Shellsort.
• After a 5-sort, elements spaced five apart
are guaranteed to be in corrected order.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-69
Shell Sort (5)

• Similarly, after a 3-sort, elements spaced


three apart are guaranteed to be in sorted
order, relative to each other.
• An hK ­sorted array that is then hK-1--sorted
remains hK -sorted. If this were not the case,
the algorithm would likely be of little value
because work done by early phases would be
undone by later phases.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-70
Shell Sort Example 1

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-71
Shell Sort Example 1 (2)

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-72
Shell Sort Example 2

[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ]
• Start with a step-size of 5, visualize this as
breaking the list of numbers into a table
with 5 columns.

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-73
Shell Sort Example (2)

• We then sort each column:

[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]
…..

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-74
Java Implementation of Shell Sort

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-75
public class shellSort {
public static <AnyType extends Comparable<? super AnyType>>
void shellsort( AnyType [ ] a ) {
for( int gap = a.length / 2;
gap > 0; gap = gap == 2 ? 1 : (int) ( gap / 2.2 ) )
for( int i = gap; i < a.length; i++ ){
AnyType tmp = a[ i ];
int j=i;
for (; j >= gap && tmp.compareTo ( a[ j - gap ] ) < 0; j -= gap )
a[ j ] = a[ j - gap ];

}
a[ j ] = tmp;
Shell Sort Program
}
public static void main (String args []) {
Integer a [] = {8, 4, 0, 6, 74, 23, 14, 1, 0, 45, 4, 8};
shellsort(a);
for (int i=0; i<a.length;i++)
System.out.println (a[i]);
}
}
Copyright © 2006 Pearson Addison-Wesley. All rights reserved.
8-76
Shell Sort Implementation

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-77
Shell Sort (7)

• The running time depends heavily on the


choice of increment.
• When increment is used , the worst case is
O(N2).

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-78
Sorting Algorithms Compared

http://www.cprogramming.com/tutorial/computersciencetheory/sortcomp.html

Copyright © 2006 Pearson Addison-Wesley. All rights reserved.


8-79

You might also like