Basic sorting Selection sort Correctness January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 1
Queue operations • A queue should implement at least the first two of these operations: – enqueue – insert item at the back of the queue – dequeue – remove an item from the front – peek – return the item at the front of the queue without removing it – isEmpty – check if the queue does not contain any items • Like stacks, it is assumed that these operations will be implemented efficiently – That is, in constant time January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 2
Circular arrays • Trick : use a circular array to insert and remove items from a queue in constant time • The idea of a circular array is that the end of the array “wraps around” to the start of the array 7 0 6 1 2 0 2 3 4 6 1 5 7 5 3 4 January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 3
The modulo operator • The mod operator (%) calculates remainders: – 1%5 = 1, 2%5 = 2, 5%5 = 0, 8%5 = 3 • The mod operator can be used to calculate the front and back positions in a circular array – Thereby avoiding comparisons to the array size – The back of the queue is: Member attributes: • (front + num) % arrlength int front; • where num is the number of items in the queue int arrlength; int* arr; – After removing an item, the front of the queue is: int num; • (front + 1) % arrlength January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 4
Array queue example 0 0 1 Queue q; front num q.enqueue(6); 6 0 1 2 3 4 5 Insert item at (front + num) % queue.length, then increment num January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 5
Array queue example 2 0 1 3 5 4 Queue q; front num q.enqueue(6); q.enqueue(4); q.enqueue(7); 6 4 7 3 8 q.enqueue(3); q.enqueue(8); 0 1 2 3 4 5 q.dequeue(); Insert item at (front + num) % queue.length, then increment num q.dequeue(); Remove item at front, then decrement num and make front = (front + 1) % queue.length January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 6
Array queue example 2 5 3 4 Queue q; front num q.enqueue(6); q.enqueue(4); q.enqueue(7); 5 7 3 8 9 q.enqueue(3); q.enqueue(8); 0 1 2 3 4 5 q.dequeue(); Insert item at (front + num) % queue.length, then increment num q.dequeue(); Remove item at front, then decrement num q.enqueue(9); and make front = (front + 1) % queue.length q.enqueue(5); Need to check that the back of the queue does not overtake the front January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 7
Array queue resizing • Suppose we have an array-based queue and we have performed some enqueue and dequeue operations – Then we perform more enqueues to fill the array – How should we resize the array to allow for more enqueue operations? 12 5 76 33 2 41 front ? ? ? ? ? ? ? ? ? ? ? ? January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 8
Queue implementation Using a Linked List • Removing items from the front of the queue is straightforward • Items should be inserted at the back of the queue in constant time – So we must avoid traversing through the list – Use a second node pointer to keep track of the node at the back of the queue • Requires a little extra administration Member attributes: Node* front; Node* back; int num; January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 9
List queue example Queue q; q.enqueue(6); front 6 q.enqueue(4); q.enqueue(7); 4 back q.enqueue(3); q.dequeue(); 7 3 January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 10
Selection sort January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 11
Algorithm analysis – simple sorting Selection sort • Suppose we are playing a card game (alcoholic beverages optional) and I have dealt you a random hand of cards – How might you organize your hand (algorithmically)? • Selection sort is a simple sorting algorithm that repeatedly finds the smallest item – we select the smallest item to put into place – The array is divided into a sorted part and an unsorted part • Repeatedly swap the first unsorted item with the smallest unsorted item – Starting with the element with index 0, and – Ending with last but one element (index 𝑜 − 1 ) January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 12
Selection sort 23 41 33 81 7 19 11 45 Find smallest unsorted item: 7 comparisons 7 41 33 81 23 19 11 45 Find smallest unsorted item: 6 comparisons 7 11 33 81 23 19 41 45 Find smallest unsorted item: 5 comparisons 7 11 19 81 23 33 41 45 Find smallest unsorted item: 4 comparisons Find smallest unsorted item: 3 comparisons 7 11 19 23 81 33 41 45 7 11 19 23 33 81 41 45 Find smallest unsorted item: 2 comparisons 7 11 19 23 33 41 81 45 Find smallest unsorted item: 1 comparison 7 11 19 23 33 41 45 81 Sorted January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 13
Selection sort comparison operations Unsorted elements Comparisons 𝑜 𝑜 − 1 𝑜 − 1 𝑜 − 2 … … 3 2 2 1 1 0 𝑜 𝑜 − 1 2 January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 14
Selection sort algorithm void SelectionSort(vector<int>& arr) { for (int i = 0; i < arr.size() -1; ++i) { int smallest = i; // Find the index of the smallest element for (int j = i + 1; j < arr.size(); ++j) { if (arr[j] < arr[smallest]) Inner loop: 𝑜 − 𝑗 times { Outer loop: each, smallest = j; 𝑜 times 𝑜 𝑜 − 1 2 times total } } // Swap the smallest with the current item temp = arr[i];{ arr[i] = arr[smallest]; arr[smallest] = temp; } } January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 15
Selection sort summary • In broad terms and ignoring the actual number of executable statements, selection sort – Makes 𝑜 ∗ 𝑜 − 1 2 comparisons, regardless of the original order of the input – Performs 𝑜 − 1 swaps • Neither of these operations are substantially affected by the organization of the input • When might we use Selection sort? – In asymptotic terms, how many swaps are done? – This might work in extremely limited systems where reads are cheap, but writes are expensive January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 16
Analyzing loops Proving algorithm correctness using loop invariants • Loop invariants – Properties of the algorithm or structure that are always true (i.e. do not vary) at particular points in the program – Within a loop body, these properties may become violated briefly, but the rest of the loop instructions should fix the properties for the next iteration • E.g. we have an algorithm for Selection sort. How can we prove that it really works for all possible input configurations? January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 17
Selection sort correctness Inner loop • The inner loop's purpose is to identify the index of the smallest value in the unordered portion of the array – use loop invariant to rigourously prove that this happens • A partial inner loop progress: int smallest = i; // Find the index of the smallest element for (int j = i + 1; j < arr.size(); ++j) { if (arr[j] < arr[smallest]) smallest = j; } ... 7 9 4 8 12 6 2 5 3 16 smallest: 14 15 16 17 18 19 20 21 22 𝑗 𝑘 January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 18
Selection sort Inner loop correctness • Invariant property: – Before iteration 𝑘 of the inner loop, smallest contains the index of the smallest element of 𝑏𝑠𝑠 𝑗. . 𝑘 − 1 – Plain English version: smallest contains the index of the smallest element seen so far – Use induction to build up towards loop termination, where "so far" is the entire unordered subarray • Base case: 𝑘 = 𝑗 + 1 – Before the first iteration of the inner loop, the invariant states that smallest contains the index of the smallest element of 𝑏𝑠𝑠 𝑗. . 𝑗 – This is set explicitly by the line int smallest = i; – Therefore the loop invariant holds in the base case January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 19
Selection sort Inner loop correctness • Invariant property: – Before iteration 𝑘 of the inner loop, smallest contains the index of the smallest element of 𝑏𝑠𝑠 𝑗. . 𝑘 − 1 • Maintenance: 𝑘 = 𝑙, 𝑗 ≤ 𝑙 < arr.size() – Assume loop invariant holds prior to processing index 𝑙 , i.e. smallest contains the index of the smallest element of 𝑏𝑠𝑠 𝑗. . 𝑙 − 1 – Case 1: arr[k] < arr[smallest] • By assumption, 𝑏𝑠𝑠 𝑙 is smaller than any element of 𝑏𝑠𝑠 𝑗. . 𝑙 − 1 • smallest is set to 𝑙 , and contains the index of the smallest element of 𝑏𝑠𝑠 𝑗. . 𝑙 , thus loop invariant holds after processing index 𝑙 – Case 2: arr[k] ≮ arr[smallest] • By assumption, 𝑏𝑠𝑠 𝑙 is not smaller than any element of 𝑏𝑠𝑠 𝑗. . 𝑙 − 1 • No action taken, and smallest contains the index of the smallest element of 𝑏𝑠𝑠 𝑗. . 𝑙 , thus loop invariant holds after processing index 𝑙 January 18, 2019 Cinda Heeren / Will Evans / Geoffrey Tien 20
Recommend
More recommend