500 likes | 515 Views
Sorting. Chapter 13 presents several common algorithms for sorting an array of integers. Two slow but simple algorithms are Selectionsort and Insertionsort. Data Structures and Other Objects Using C++.
E N D
Sorting • Chapter 13 presents several common algorithms for sorting an array of integers. • Two slow but simple algorithms are Selectionsort and Insertionsort. Data Structures and Other Objects Using C++
The picture shows an array of six integers that we want to sort from smallest to largest Sorting an Array of Integers [0][1] [2] [3] [4] [5]
Start by finding the smallest entry. The Selectionsort Algorithm [0][1] [2] [3] [4] [5]
Start by finding the smallest entry. Swap the smallest entry with the first entry. The Selectionsort Algorithm [0][1] [2] [3] [4] [5]
Start by finding the smallest entry. Swap the smallest entry with the first entry. The Selectionsort Algorithm [0][1] [2] [3] [4] [5]
Part of the array is now sorted. The Selectionsort Algorithm Sorted side Unsorted side [0][1] [2] [3] [4] [5]
Find the smallest element in the unsorted side. The Selectionsort Algorithm Sorted side Unsorted side [0][1] [2] [3] [4] [5]
Find the smallest element in the unsorted side. Swap with the front of the unsorted side. The Selectionsort Algorithm Sorted side Unsorted side [0][1] [2] [3] [4] [5]
We have increased the size of the sorted side by one element. The Selectionsort Algorithm Sorted side Unsorted side [0][1] [2] [3] [4] [5]
The process continues... The Selectionsort Algorithm Sorted side Unsorted side Smallest from unsorted [0][1] [2] [3] [4] [5]
The process continues... The Selectionsort Algorithm Sorted side Unsorted side Swap with front [0][1] [2] [3] [4] [5]
The process continues... The Selectionsort Algorithm Sorted side is bigger Sorted side Unsorted side [0][1] [2] [3] [4] [5]
The process keeps adding one more number to the sorted side. The sorted side has the smallest numbers, arranged from small to large. The Selectionsort Algorithm Sorted side Unsorted side [0][1] [2] [3] [4] [5]
We can stop when the unsorted side has just one number, since that number must be the largest number. Sorted side Unsorted side The Selectionsort Algorithm [0][1] [2] [3] [4] [5]
The array is now sorted. We repeatedly selected the smallest element, and moved this element to the front of the unsorted side. The Selectionsort Algorithm [0][1] [2] [3] [4] [5]
Selectionsort Implementation for (i = n – 1; i > 0; --i) { index_of_largest = 0; largest = data[0]; for (j = 1; j <= i; ++j) { if (data[j] > largest) largest = data[j]; index_of_largest = j; } swap(data[i], data[index_of_largest]); }
Selectionsort Time Analysis • Best case: O(n2) • Worst case: O(n2) • Average case: O(n2)
The Insertionsort algorithm also views the array as having a sorted side and an unsorted side. The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
The sorted side starts with just the first element, which is not necessarily the smallest element. Sorted side Unsorted side The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
The sorted side grows by taking the front element from the unsorted side... Sorted side Unsorted side The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
...and inserting it in the place that keeps the sorted side arranged from small to large. Sorted side Unsorted side The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
In this example, the new element goes in front of the element that was already in the sorted side. Sorted side Unsorted side The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
Sometimes we are lucky and the new inserted item doesn't need to move at all. Sorted side Unsorted side The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
Sometimes we are lucky twice in a row. Sorted side Unsorted side The Insertionsort Algorithm [0][1] [2] [3] [4] [5]
Copy the new element to a separate location. Sorted side Unsorted side How to Insert One Element [0][1] [2] [3] [4] [5]
Shift elements in the sorted side, creating an open space for the new element. How to Insert One Element [0][1] [2] [3] [4] [5]
Shift elements in the sorted side, creating an open space for the new element. How to Insert One Element [0][1] [2] [3] [4] [5]
Continue shifting elements... How to Insert One Element [0][1] [2] [3] [4] [5]
Continue shifting elements... How to Insert One Element [0][1] [2] [3] [4] [5]
...until you reach the location for the new element. How to Insert One Element [0][1] [2] [3] [4] [5]
Copy the new element back into the array, at the correct location. Sorted side Unsorted side How to Insert One Element [0][1] [2] [3] [4] [5]
The last element must also be inserted. Start by copying it... Sorted side Unsorted side How to Insert One Element [0][1] [2] [3] [4] [5]
How many shifts will occur before we copy this element back into the array? A Quiz [0][1] [2] [3] [4] [5]
Four items are shifted. A Quiz [0][1] [2] [3] [4] [5]
Four items are shifted. And then the element is copied back into the array. A Quiz [0][1] [2] [3] [4] [5]
Timing and Other Issues • Both Selectionsort and Insertionsort have a worst-case time of O(n2), making them impractical for large arrays. • But they are easy to program, easy to debug. • Insertionsort also has good performance when the array is nearly sorted to begin with. • But more sophisticated sorting algorithms are needed when good performance is needed in all cases for large arrays.
Merge Sort --- Divide and Conquer • Divide (into two equal parts) • Conquer (solve for each part separately) • Combine separate solutions • Merge sort • Divide into two equal parts • Sort each part using merge-sort (recursion!!!) • Merge two sorted subsequences
void mergesort(int data[], size_t n) { size_t n1; size_t n2; if(n > 1) { n1 = n / 2; n2 = n – n1; mergesort(data, n1); mergesort((data + n1), n2); merge(data, n1, n2); } } Merge Sort Implementation merge: • Initialize copied, copied1, and copied2 to 0 • While (both halves of the array have more elements to copy) if (data[copied1] <= (data + n1)[copied2]) temp[copied++] = data[copied + 1]; else temp[copied++] = (data + n1)[copied2++]; • Copy any remaining entries from the left or right subarray • Copy the element from temp back to data
Merge Sort Time Analysis • Worst case: O(n log n)
Quick Sort --- Divide and Conquer • Suppose we know some particular value that belongs in the middle of the array --- pivot • Recursively partition the array based on the pivot element
Quick Sort Implementation Void quicksort(int data[], size_t n) { size_t pivot_index; size_t n1, n2; if(n > 1) { partition(data, n, pivot_index); n1 = pivot_index; n2 = n – n1 – 1; quicksort(data, n1); quicksort((data + pivot_index + 1), n2); } }
Partition Implementation • Initialize values: pivot = data[0]; too_big_index = 1; too_small_index = n-1; • while (too_big_index > too_small_index) • while (too_big_index < n & data[too_big_index] <= pivot) too_big_index ++; • while (data[too_small_index] > pivot) too_small_index --; • if (too_big_index < too_small_index) swap(data[too_big_index], data[too_small_index]); • Move the pivot element to its correct position • Pivot_index = too_small_index; • data[0] = data[pivot_index]; • data[pivot_index] = pivot;
Quick Sort Time Analysis • Worst case: O(n2) • Average case: O(n log n)
Heapsort • Max-heap property: • Min-heap property:
Heap Sort Time Analysis • Worst case: O(n log n)