This book is new. If you'd like to go through it, then join the Learn Code Forum to get help while you attempt it. I'm also looking for feedback on the difficulty of the projects. If you don't like public forums, then email firstname.lastname@example.org to talk privately.
Exercise 21: Binary Search
The Binary Search algorithm is a simple way to find an item in an already sorted list of items. It's easily described as taking a sorted list and continually partitioning it into halves until you either find it or you run out. If you did the complete Exercise 20, then this exercise should be relatively easy.
If we want to find a number X in an already sorted list of numbers we would do this:
- Get the number in the middle of the list (M) and compare it to X.
- If X == M, you're done.
- If X > M, then find the middle of M+1 to the end of the list.
- If X < M, then find the middle of M-1 to the beginning of the list.
- Repeat, until either you find X or you have only 1 element left.
This works for anything that you can compare with equality. It will work on strings, numbers, and anything else you can order consistently.
Your BSTree should already be doing a get operation that's similar to the binary search. The difference is the BSTree is already partitioned, so there's no need to do any more. In this exercise you'll implement the binary search for the DoubleLinkedList, Python's list, and compare those to the BSTree.get performance. Your goal is to learn the following:
- How well does the BSTree compare to Python's list for simply finding some items?
- How poorly does binary search work with DoubleLinkedList?
- Do your pathological cases for BSTree also cause problems for a binary search on list?
When analyzing the performance, don't include the time it takes to sort the numbers. That's important when doing a global optimization, but in this case you only care about how fast the binary search works. You can also use Python's built-in list sorting algorithms to sort your list since that's not the point. This exercise is all about how fast search is between the three data structures.
- Find out what the maximum number of possible comparisons is that this algorithm needs to make. Try to figure it out on your own first, and then research the algorithm to find out what the real answer is. After that just memorize the real answer.
- Can any of your optimizations here be applied to the sorting algorithms?
- Try to visualize what this algorithm is doing in each data structure. For example, in the DoubleLinkedList you can almost think of it as walking back and forth until it finds the answer.
- To give yourself an extra challenge, try to make the DoubleLinkedList into a sorted linked list where every insert is always at the sorted position. Now write your performance analysis to include adding elements and sorting the lists of numbers to see how that improves total performance.
Research other search algorithms, especially for strings. Many of these will be difficult to implement in Python because of the way Python's strings are implemented, but give it a try anyway.