28
Sorting II/ Slide 1 Sorting Arrange keys in ascending or descending order. One of the most fundamental problems. First computer program was a sorting program (ENIAC, Univ. of Penn.) Studied: selection sort, insertion sort, merge sort (?) and heap sort

Sorting Arrange keys in ascending or descending order

Embed Size (px)

DESCRIPTION

Sorting Arrange keys in ascending or descending order. One of the most fundamental problems. First computer program was a sorting program (ENIAC, Univ. of Penn.) Studied: selection sort, insertion sort, merge sort (?) and heap sort. Recall two basic sorting algorithms: selection sorting - PowerPoint PPT Presentation

Citation preview

Page 1: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 1

Sorting

Arrange keys in ascending or descending order.

One of the most fundamental problems. First computer program was a sorting program (ENIAC, Univ. of Penn.)

Studied: selection sort, insertion sort, merge sort (?) and heap sort

Page 2: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 2

Recall two basic sorting algorithms: selection sorting

insertion sorting

We will revisit the applet at:http://math.hws.edu/TMCM/java/xSortLab/

Page 3: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 3

Merge sortingIn lecture 2, we studied the merging step.

Merging: Take two sorted arrays and combine them into one sorted array.

Merge sorting and heap sorting are two algorithms that take O(n log n) time in the worst-case. (best possible)

Page 4: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 4

Code for merging step

void merge( vector<Comparable> & a, vector<Comparable> & tmpArray,int leftPos, int rightPos, int rightEnd )

{

int leftEnd = rightPos - 1;

int tmpPos = leftPos;

int numElements = rightEnd - leftPos + 1;

// Main loop

while( leftPos <= leftEnd && rightPos <= rightEnd )

if( a[ leftPos ] <= a[ rightPos ] )

tmpArray[ tmpPos++ ] = a[ leftPos++ ];

else

tmpArray[ tmpPos++ ] = a[ rightPos++ ];

Page 5: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 5

while( leftPos <= leftEnd )// Copy rest of first half

tmpArray[ tmpPos++ ] = a[ leftPos++ ];

while( rightPos <= rightEnd )//Copy rest of right half

tmpArray[ tmpPos++ ] = a[ rightPos++ ];

// Copy tmpArray back

for( int i = 0; i < numElements; i++, rightEnd-- )

a[ rightEnd ] = tmpArray[ rightEnd ];

}

Page 6: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 6

Merge sorting algorithm

Recursive version of merge sorting:To sort the array A between indices low and high: if (high == low) return; mid = (low + high) /2; recursively sort A between indices low and mid; recursively sort A between indices mid+1 and high; merge the two sorted halves.

Page 7: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 7

Merge sorting - Code

void mergeSort( vector<Comparable> & a, vector<Comparable> & tmpArray, int left, int right ){ if( left < right ) { int center = ( left + right ) / 2; mergeSort( a, tmpArray, left, center ); mergeSort( a, tmpArray, center + 1, right ); merge( a, tmpArray, left, center + 1, right ); }}

Page 8: Sorting  Arrange keys in ascending or descending order

Quicksort - Introduction

Fastest known sorting algorithm in practice

Average case: O(N log N) Worst case: O(N2)

But, the worst case rarely occurs. Another divide-and-conquer recursive

algorithm like mergesort

Page 9: Sorting  Arrange keys in ascending or descending order

Quicksort

Divide step: Pick any element (pivot) v in S Partition S – {v} into two

disjoint groups S1 = {x S – {v} | x v} S2 = {x S – {v} | x v}

Conquer step: recursively sort S1 and S2

Combine step: combine the sorted S1, followed by v, followed by the sorted S2

v

v

S1 S2

S

Page 10: Sorting  Arrange keys in ascending or descending order

Example: Quicksort

Page 11: Sorting  Arrange keys in ascending or descending order

Example: Quicksort...

Page 12: Sorting  Arrange keys in ascending or descending order

Pseudocode

Input: an array A[p, r]

Quicksort (A, p, r) { if (p < r) {

q = Partition (A, p, r) //q is the position of the pivot element

Quicksort (A, p, q-1)Quicksort (A, q+1, r)

}}

Page 13: Sorting  Arrange keys in ascending or descending order

Partitioning

Partitioning Key step of quicksort algorithm Goal: given the picked pivot, partition the

remaining elements into two smaller sets Many ways to implement Even the slightest deviations may cause

surprisingly bad results. We will learn an easy and efficient

partitioning strategy here. How to pick a pivot will be discussed later

Page 14: Sorting  Arrange keys in ascending or descending order

Partitioning Strategy

Want to partition an array A[left .. right] First, get the pivot element out of the way by

swapping it with the last element. (Swap pivot and A[right])

Let i start at the first element and j start at the next-to-last element (i = left, j = right – 1)

pivot

i j

5 6 4 6 3 12 19 5 6 4 63 1219

swap

Page 15: Sorting  Arrange keys in ascending or descending order

Partitioning Strategy Want to have

A[p] <= pivot, for p < i A[p] >= pivot, for p > j

When i < j Move i right, skipping over elements smaller than the pivot Move j left, skipping over elements greater than the pivot When both i and j have stopped

A[i] >= pivot A[j] <= pivot

i j

5 6 4 63 1219

i j

5 6 4 63 1219

Page 16: Sorting  Arrange keys in ascending or descending order

Partitioning Strategy When i and j have stopped and i is to the

left of j Swap A[i] and A[j]

The large element is pushed to the right and the small element is pushed to the left

After swapping A[i] <= pivot A[j] >= pivot

Repeat the process until i and j cross

swap

i j

5 6 4 63 1219

i j

5 3 4 66 1219

Page 17: Sorting  Arrange keys in ascending or descending order

Partitioning Strategy

When i and j have crossed Swap A[i] and pivot

Result: A[p] <= pivot, for p < i A[p] >= pivot, for p > i

i j

5 3 4 66 1219

ij

5 3 4 66 1219

ij

5 3 4 6 6 12 19

http://math.hws.edu/TMCM/java/xSortLab/

Page 18: Sorting  Arrange keys in ascending or descending order

Implementation of partitioning stepint partition(A, left, right){

int pivot = A[right];

int i = left, j = right-1;

for (; ;) {

while (a[i] < pivot && i <= right) i++;

while (pivot < a[j] && j >= left) j--;

if (i < j)

{swap(a[i], a[j]);

i++; j--;

}

else break;

}

swap(A[i], A[right]);

return i;

}

Page 19: Sorting  Arrange keys in ascending or descending order

Small arrays

For very small arrays, quicksort does not perform as well as insertion sort how small depends on many factors, such as the

time spent making a recursive call, the compiler, etc

Do not use quicksort recursively for small arrays Instead, use a sorting algorithm that is efficient

for small arrays, such as insertion sort

Page 20: Sorting  Arrange keys in ascending or descending order

Picking the Pivot Use the first element as pivot

if the input is random, then we can choose the key in position A[right] as pivot.

if the input is sorted (straight or reverse) all the elements go into S2 (or S1) this happens consistently throughout the

recursive calls Results in O(n2) behavior (Analyze this case

later) Choose the pivot randomly

generally safe random number generation can be expensive

Page 21: Sorting  Arrange keys in ascending or descending order

Picking the Pivot

Use the median of the array Partitioning always cuts the array into

roughly half An optimal quicksort (O(N log N)) However, hard to find the exact median

Page 22: Sorting  Arrange keys in ascending or descending order

Pivot: median of three We will use median of three

Compare just three elements: the leftmost, rightmost and center Swap these elements if necessary so that

A[left] = Smallest A[right] = Largest A[center] = Median of three

Pick A[center] as the pivot Swap A[center] and A[right – 1] so that pivot is at second last position (why?)

median3

Page 23: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 23

Pivot: median of three

Code for partitioning with median of three pivot:

Page 24: Sorting  Arrange keys in ascending or descending order

Pivot: median of three

pivot

5 6 4

6

3 12 192 13 6

5 6 4 3 12 192 6 13

A[left] = 2, A[center] = 13, A[right] = 6

Swap A[center] and A[right]

5 6 4 3 12 192 13

pivot

65 6 4 3 12192 13

Choose A[center] as pivot

Swap pivot and A[right – 1]

Note we only need to partition A[left + 1, …, right – 2]. Why?

Page 25: Sorting  Arrange keys in ascending or descending order

Sorting II/ Slide 25

Implementation of partitioning step

Works only if pivot is picked as median-of-three. A[left] <= pivot and

A[right] >= pivot Thus, only need to

partition A[left + 1, …, right – 2]

j will not run past the end because a[left] <= pivot

i will not run past the end because a[right-1] = pivot

Page 26: Sorting  Arrange keys in ascending or descending order

Main Quicksort Routine

For small arrays

Recursion

Choose pivot

Partitioning

Page 27: Sorting  Arrange keys in ascending or descending order

Quicksort Faster than Mergesort Both quicksort and mergesort take O(N log N) in the

average case. Why is quicksort faster than mergesort?

The inner loop consists of an increment/decrement (by 1, which is fast), a test and a jump.

Mergesort involves a large number of data movements. Quicksort is done in-place.

Page 28: Sorting  Arrange keys in ascending or descending order

Performance of quicksort

Worst-case: takes O(n2) time. Average-case: takes O(n log n) time.

On typical inputs, quicksort runs faster than other algorithms.

Compare various sorting algorithms at:

http://www.geocities.com/siliconvalley/network/1854/Sort1.html