• No results found

Binary search is a logarithmic algorithm used to search for numbers in a list, but the numbers have to be ordered. Remember this:, in order for an algorithm to be logarithmic, it needs to either be dividing or multiplying to a solution. Any guesses how binary search works? Binary search works by continually cutting the list in half. The algorithm picks a number in the middle of a list, and looks at whether it’s the right number. If it is the right number, the search is complete. If it’s not the right number, the algorithm t hrows away half the list . If the number was too big, it throws away everything above the number it selected. If the number was too small, it throws away everything below the number it selected.

Image we have an ordered list from 1 to 10, and we want to search for the number 3. Our list looks like this:

[1,2,3,4,5,6,7,8,9,10]

Our algorithm would first pick the number 5 because it’s in the middle of the list. Since 5 is not the number we are looking for, and 3 is smaller than five, our algorithm would throw out everything above 5. Now our list looks like this:

[1,2,3,4,5]

Our list would now pick the number three, since it’s in the middle of the list. Since 3 is the number we are looking for, our algorithm would stop and return that the number 3 was found in our list. Notice our algorithm only took two steps to figure out three was in our list. If we searched through the list linearly, one by one, looking for the number three, it would takes us three steps. Here is an example of a binary search algorithm searching for the number 3:

def binary_search (number_list, number):

"""Logarithmic binary search algorithm.

:param number_list: List of ordered integers.

:param number: Integer to search for in the passed in list.

:return: True if the number is found, otherwise False.

"""

first = 0

last = len(number_list)-1 number_found = False

while first <= last and not number_found:

middle = (first + last)/2

if number_list[middle] == number:

number_found = True else :

if number < number_list[middle]:

last = middle - 1 else :

first = middle + 1 return number_found

binary_search([1,2,3,4,5,6,7,8,9,10], 3)

We use a while loop that continues as long as the variable first is not greater than or equal to the variable last, and the variable not_true is False.

We calculate the middle index of the list by adding the first index of the list with the last index of the list and dividing them by two. The reason we subtract one from last is because the length of a list is calculated starting from one, whereas indexes start at zero.

We check to see if the middle number is the number we are looking for by looking up the middle number in our list with number_list[middle]. If the middle number is the number we are looking for, not_true is set to True, and we exit the loop. Otherwise, we check to see if the number we are looking for is bigger or smaller than the middle number. If our middle number is smaller than the number we are looking for, we change last to the middle index - 1, which on the next loop will split the list in half with everything smaller than our current

middle number, whereas if our middle number is bigger than the number we are looking for, we change first to middle + 1, dividing the list in half so it contains everything bigger than our middle number.

Recursion

Recursion is notorious as one of the toughest concepts for new programmers to grasp. If it is confusing to you at first, don’t worry, it’s confusing to everyone. Recursion is a method of solving problems by breaking the problem up into smaller and smaller pieces until it can be easily solved. This is achieved with a function that calls itself. Any problem that can be solved recursively can also be solved iteratively, however in certain cases, recursion offers a more elegant solution.

A recursive algorithm must follow the three laws of recursion:

“1. A recursive algorithm must have a base case .

2. A recursive algorithm must change its state and move toward the base case.

3. A recursive algorithm must call itself, recursively.”

Let’s go over an example of a recursive function that has all three, a function to print out the lyrics to the popular children’s song “99 Bottles of Beer on the Wall” 19 :

def bottles_of_beer (bob):

""" Use recursion to print the bottles of beer song.

:param bob: Integer number of beers that arestart on the wall.

"""

if bob < 1:

print "No more bottles of beer on the wall. No more bottles of beer."

return tmp = bob

bob -= 1

print "{} bottles of beer on the wall. {} bottles of beer. Take one down, pass it around, {} bottles of beer on the wall.".format(tmp, tmp, bob)

bottles_of_beer(bob) bottles_of_beer(99)

>> 99 bottles of beer on the wall. 99 bottles of beer. Take one down, pass it around, 98 bottles of beer on the wall.

>> 98 bottles of beer on the wall. 98 bottles of beer. Take one down, pass it around, 97 bottles of beer on the wall.

>>No more bottles of beer on the wall. No more bottles of beer.

In this example, the base case is:

if bob < 1:

print "No more bottles of beer on the wall. No more bottles of beer."

return

The base case of a recursive algorithm is what finally stops the algorithm from running.

If you have a recursive algorithm without a base case, it will continue to call itself forever, and you will get a runtime error saying the maximum recursion depth has been exceeded. The line:

bob -= 1

satisfies our second rule that we must move toward our base case. In our example, we passed in the number “99” to our function as the parameter bob. Since our base case is bob being less than 1, and because bob starts at 99, without this line we will never reach our base case, which will also give us a maximum recursion depth runtime error.

Our final rule is satisfied with : bottles_of_beer(bob)

With this line, we are calling our function. The function will get called again, but with one important difference. Instead of passing in 99 like the first time the function was called, this time 98 will be passed in, because of rule number two. The third the function is called 97 will be called. This will continue to happen until eventually bob is equal to 0, and we hit our base case. At that point we print “No more bottles of beer on the wall. No more bottles of beer.”

and return, signaling the algorithm to stop.

Let’s go over one more recursive algorithm. Say you are given the following problem:

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

For example:

Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.