SIMPLE Sorting Sorting is a typical operation to

  • Slides: 30
Download presentation
SIMPLE Sorting • Sorting is a typical operation to put the elements in an

SIMPLE Sorting • Sorting is a typical operation to put the elements in an array in order. • Internal Sorts [for small data sets] selection bubble (exchange) • External Sorts [for large data sets]

Find smallest element, and put at the head of the list, repeat with remainder

Find smallest element, and put at the head of the list, repeat with remainder of list Selection Sort index (k) sm_index 21 13 9 15 17 0 2 swap 21, 9 9 13 21 15 17 1 1 swap 13, 13 9 13 21 15 17 2 3 swap 21, 15 9 13 15 21 17 3 4 swap 21, 17 9 13 15 17 21

Selection Sort void sort(double [5]); void swap(double [5], int); // prototypes void main(void) {

Selection Sort void sort(double [5]); void swap(double [5], int); // prototypes void main(void) { int index; double my_list[ ] = {21, 13, 9, 15, 17}; sort(my_list); // function call cout<<"n. The sorted array is: n"; for(index=0; index<5; index++) cout<<'t'<<my_list[index]<<endl; }

Selection Sort void sort(double test. Array[5]) { int n, k, sm_index, moves=0; } double

Selection Sort void sort(double test. Array[5]) { int n, k, sm_index, moves=0; } double smallest; for(k=0; k<4; k++) // size-1 = number of passes { smallest=test. Array[k]; sm_index=k; for(n=k+1; n<5; n++) // size = # elem. to look at if(test. Array[n]<smallest) { smallest=test. Array[n]; sm_index=n; } swap(test. Array, sm_index, k); // call to swap() }

Bubble Sort 21 13 9 25 17 • Put smaller first 13 21 9

Bubble Sort 21 13 9 25 17 • Put smaller first 13 21 9 25 17 • Put smaller first 13 9 21 25 17 • No change 13 9 21 25 17 • Put smaller first

Bubble Sort 13 9 21 17 25 • Begin again and put smaller first

Bubble Sort 13 9 21 17 25 • Begin again and put smaller first 9 13 21 17 25 • No change 9 13 21 17 25 • Put smaller first 9 13 17 21 25

A Bubble Sort Function void bubble_sort(int array[ ], int length) { int j, k,

A Bubble Sort Function void bubble_sort(int array[ ], int length) { int j, k, flag=1, temp; for(j=1; j<=length && flag; j++) { flag=0; // false for(k=0; k < (length-j); k++) { if (array[k+1] > array[k]) // > low to high { temp=array[k+1]; // swap array[k+1]= array[k]; array[k]=temp; flag=1; // indicates a swap } } // has occurred

Insertion sort: Pick up the cards one at a time. When a card is

Insertion sort: Pick up the cards one at a time. When a card is picked up put it in the “already picked up list” in its correct position. *

G D Z F B E 0 1 2 3 4 5 D G

G D Z F B E 0 1 2 3 4 5 D G Z F B E 0 1 2 3 4 5 D F G Z B E 0 1 2 3 4 5 B D F G Z E 0 1 2 3 4 5 B D E F G Z 0 1 2 3 4 5 Index number

Insertion. Sort( int a[], int n) { int I; loc; temp; for (I =

Insertion. Sort( int a[], int n) { int I; loc; temp; for (I = 1; I < n; I++) { temp = a[I]; loc = I; GET NEXT ELEMENT TO INSERT while (loc && (a[loc-1] > temp)) { a[loc] = a[loc-1]; -- loc; } a[loc] = temp; } Find its place in list -- keep moving items down until the correct locations is found

Insertion Sort Analysis: for (I = 1; I < n; I++) { temp =

Insertion Sort Analysis: for (I = 1; I < n; I++) { temp = a[I]; loc = I; Worst case: O(n 2) 1+2+3+4+5…. comparisons and moves BEST CASE? O(n) Good for mostly sorted lists Average case = O(n 2) while (loc && (a[loc-1] > temp)) { a[loc] = a[loc-1]; -- loc; } a[loc] = temp; *

Using Pointers for Sorting In the algorithms looked at the data is physically re-arranged

Using Pointers for Sorting In the algorithms looked at the data is physically re-arranged

Quicksort algorithm • Split list into two “halves” one greater than the other •

Quicksort algorithm • Split list into two “halves” one greater than the other • now split each of these two lists

Elements…………. . j Less than j Greater than j e <e s c <c

Elements…………. . j Less than j Greater than j e <e s c <c <s >e m g >c <g >s >g <m w >m <w a b c d. D e f F g h i j k l mo q s u vwy z >w

Partition • Divide the list into two halves: left and right where the left

Partition • Divide the list into two halves: left and right where the left half is smaller than the right: • ----> use a “pivot” elements less than the pivot go left, elements greater than the pivot go right

left right 98 32 45 99 101 73 67 left right 67 32 45

left right 98 32 45 99 101 73 67 left right 67 32 45 99 101 73 67 left right 67 32 45 99 101 73 99 left right 67 32 45 73 101 73 99 right left 67 32 45 73 98 101 99 Pivot = 98

int partition(int num[], int left, int right) {int pivot, temp; pivot = num[left]; //

int partition(int num[], int left, int right) {int pivot, temp; pivot = num[left]; // "capture" the pivot value, which frees up one slot while (left < right) { // scan from right to left while(num[right] >= pivot && left < right) // skip over larger or equal val right--; if (right != left) { num[left] = num[right]; // move the higher value left++; } // scan from left to right while (num[left] <= pivot && left < right) // skip over smaller or equal val left++; if (right != left) { num[right] = num[left]; // move lower value into the available slot right--; } } num[left] = pivot; // move pivot into correct position return left; } // return the pivot index

#include <iostream> using namespace std; int partition(int [], int); // function prototype int main()

#include <iostream> using namespace std; int partition(int [], int); // function prototype int main() { const int NUMEL = 7; int nums[NUMEL] = {98, 32, 45, 99, 101, 73, 67}; int i, pivot; pivot = partition(nums, 0, NUMEL-1); cout << "n. The returned pivot index is " << pivot; cout << "n. The list is now in the order: n"; for (i = 0; i < NUMEL; i++) cout << " " <<nums[i]; The pivot index is 4 cout << endl; the list is now in the order: return 0; 67 32 45 73 98 101 99 } *

Quicksort algorithm must call the partition algorithm until the “list is sorted”, I. e.

Quicksort algorithm must call the partition algorithm until the “list is sorted”, I. e. on each half recursively until the “halves” are too small Quicksort algorithm: pick pivot & partition list call quicksort(left half) call quicksort (right half)

Elements…………. . Quicksort(left) Less than j j Q(left/left) e Q(left/rgt) <e >e c <c

Elements…………. . Quicksort(left) Less than j j Q(left/left) e Q(left/rgt) <e >e c <c Quicksort(right) Greater than j Q(rgt/left) s Q(rgt/rgt) <s >s m g >c <g >g <m w >m <w a b c d. D e f F g h i j k l mo q s u vwy z 14 calls to Quicksort >w

left right 98 32 45 99 101 73 67 left Pivot = 98 right

left right 98 32 45 99 101 73 67 left Pivot = 98 right 67 32 45 99 101 73 67 left right 67 32 45 99 101 73 99 left right 67 32 45 73 101 73 99 right left 67 32 45 73 98 101 99 After the partition with the pivot=98 98 is in its final position

67 32 45 73 98 101 99 45 32 67 73 32 45 98

67 32 45 73 98 101 99 45 32 67 73 32 45 98 99 101 Result of 1 st partition 2 nd and 3 rd partition 4 th partition

void quicksort(int num[], int lower, int upper) { int i, j, pivot; pivot =

void quicksort(int num[], int lower, int upper) { int i, j, pivot; pivot = partition(num, lower, upper); if (lower < pivot) quicksort(num, lower, pivot - 1); if (upper > pivot) quicksort(num, pivot + 1, upper); return; }

#include <iostream> using namespace std; void quicksort(int [], int); // function prototypes int partition(int

#include <iostream> using namespace std; void quicksort(int [], int); // function prototypes int partition(int [], int); int main() { const int NUMEL = 7; int nums[NUMEL] = {67, 32, 45, 73, 98, 101, 99}; int i; quicksort(nums, 0, NUMEL-1); cout << "n. The sorted list, in ascending order, is: n"; for (i = 0; i < NUMEL; i++) cout << " " <<nums[i]; cout << endl; return 0; }

Quicksort(nums, 0, 6) pivot (after partition = 2) 67 32 45 73 98 101

Quicksort(nums, 0, 6) pivot (after partition = 2) 67 32 45 73 98 101 99 45 32 67 73 98 101 99 Quicksort(nums, 0, 1) 45 32 pivot (after partition = 1) 32 45 Quicksort(nums, 0, 0) 32 pivot (after partition = 0) 73 98 101 99 Quicksort(nums, 3, 6) pivot (after partition = 3) 98 101 99 99 101 99 Quicksort(nums, 4, 6) pivot (after partition = 4) Quicksort(nums, 5, 6) pivot (after partition = 6) Quicksort(nums, 5, 5) pivot (after partition = 5)

IN CLASS Assignment: Given the list of numbers below, write out the steps for

IN CLASS Assignment: Given the list of numbers below, write out the steps for the quicksort algorithm: 12 14 3 6 56 2 10 25 89 8

12 14 8 10 3 6 Piv=8 2 6 56 2 10 25 89

12 14 8 10 3 6 Piv=8 2 6 56 2 10 25 89 8 2 12 56 25 89 14 Piv=56 3 8 Piv=2 10 12 14 25 56 89 Piv=14 2 6 3 8 10 12 14 25 56 89 Piv=6 2 3 6 8 10 12 14 25 56 89 Piv=12

Analysis of Quicksort: void quicksort(int num[], int lower, int upper) { int i, j,

Analysis of Quicksort: void quicksort(int num[], int lower, int upper) { int i, j, pivot; pivot = partition(num, lower, upper); if (lower < pivot) quicksort(num, lower, pivot - 1); if (upper > pivot) quicksort(num, pivot + 1, upper); Takes O(upper-lower) since every element must be compared to the pivot

Best case time: Time(Quicksort(n)) = Partition(n) + Quicksort(n/2)+Quicksort(n/2) O(n) Partition(n/2) + Quicksort(n/4) + Partition(n/2)

Best case time: Time(Quicksort(n)) = Partition(n) + Quicksort(n/2)+Quicksort(n/2) O(n) Partition(n/2) + Quicksort(n/4) + Partition(n/2) + Quicksort(n/4) = O(n) + 2*O(n/2) + 4*(Quicksort(n/4) … = O(n) + O(n) Log(n) times…. . = O(nlogn)

Worst case time: 1 1 1 1 1 2 2 2 2 2 3

Worst case time: 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8 9 9 9 9 9 10 N times 10 10 10 = O(n 2)