Lec 09 - Searching and Sorting
Last updated
Last updated
Slides:
Given that a list is unsorted, as we have seen in Tut 02 - Functions and Conditionals, whatever method we choose, it is impossible for us "skip" any element, we must check each element in the list to safely say whether our query is in the list or not.
So, Linear Search is actually a brute-force approach that does the search by iterating through each element once in the list.
However, if our list is sorted, we can improve our algorithm greatly beacuse there is a "pattern" in our list. In this case, the pattern is a sorted list. Based on this pattern, we can implement our Bineary Search algorithm as follows:
The main idea in this algorithm is that it repeatedly cuts the range of values to search by half.
When implementing the search algorithm, always keep in mind:
How to define our search range (The use of index is inclusive or not)
When to stop our searching (How to decide the search is successful or not)
In this binary search algorithm, our search range is all the number bewteen list[i]
and list[j]
(both inclusive). And there are two cases we should stop our searching: 1) when there is no element in our search range, 2) when list[mid]
is what we want to find.
Eldon's lecture about the cost of swap is really important. Take the real world considerations into algorithm design account.
Also, the procedure to derive the complexity is interesting and there may have some places to take note of during the derivation!
The soul of this algorithm is to build a "frequency table" and then use this table to construct the sorted result.
The soul of this algorithm is to 1) partition the list into two parts, an unsorted part followed by a sorted part, 2) repeatedly selects the maximum element from the unsorted part and move it to the front of the sorted part. (For increasing sort).
Otherwise, for decreasing sort, the idea will be to find the smallest unsorted element and add it to the end of the sorted list.
The idea is that this algorithm sorts the largest number to the end until the beginning by a series of bubble pass. In each pass, we look for all possible adjacent pairs of items. Any adjacent pair that is out of order is swapped so that they are in order. So, after each pass, we will move the largest number to its correct position and in the next pass, we will exclude it.
Similar to Selection Sort*, now we partition our list into 1) a sorted one, 2) followed by an unsorted one. Then we repeatedly take the first element from the unsorted partition, find its rightful place in the sorted partition, and insert it into place. We start with a sorted partition of one element, and we end if the sorted partition contains all the elements.
When implementing the search algorithm, always keep in mind:
How to define our search range (The use of index is inclusive or not)
When to stop our searching (How to decide the search is successful or not)
In this binary search algorithm, our search range is all the number bewteen list[i]
and list[j]
(both inclusive). And there are two cases we should stop our searching: 1) when there is no element in our search range, 2) when list[mid]
is what we want to find.
The idea of binary serach is practiced in . And the idea of cutting the search range is practiced in .
This is the only sorting algorithm that has the chance to take to sort a list.
The time complexity is
The time complexity is
One thing to note is that every time you see time complexity in the question, try to think of binary search.