1

I'm trying to find the minimum value in a list of integers using recursion. The main idea is that if the list is only one element long, this element is my minimum. Else, I divide the list onto two smaller lists of the same size, look for minimum value in both of them and then compare which one is smaller. The code looks like this:

def minimum(a,l,p):
    if l == p:
        return a[l]
    else:
        m1 = minimum(a,l, (l+p)/2)
        m2 = minimum(a, (l+p)/2 + 1, p)
        if m1 < m2:
            return m1
        else:
            return m2

It doesn't seem to be difficult, however when I tried to run this function for a sample list, I got the following error: "RecursionError: maximum recursion depth exceeded in comparison". Is something wrong with the algorithm or maybe I should look somewhere else for the reason fo this problem?

Paweł
  • 67
  • 1
  • 8
  • 4
    Not again: *recursion* is a bad idea for things that have no *recursive* structure. If you want to calculate the minimum element of a *tree* fine, but not a list. As to why it does not work? Because you work with floating points after a while, use `(l+p)//2` instead of `(l+p)/2`. – Willem Van Onsem Jan 03 '18 at 20:47
  • 1
    What are `l`,`a`, and `p`? What ever they are, `l == p` may not be a suitable base case to stop the recursion. – Miket25 Jan 03 '18 at 20:49
  • 1
    Unless you're trying to experiment and learn about recursion, you really should just use `min(my_list)` and be done with it – HFBrowning Jan 03 '18 at 20:50

3 Answers3

2

Your recursive strategy mentioned is similar a binary search, and it is most effected when traversing a tree to find a generic value as the tree is assumed to be structured in a sorted manner for maximum transversal efficiency. If you are truly intent on solving the problem with recursion, however, you can iterate over the list itself:

def minimum(l, val):
  if not l[1:]:
     return val
  return minimum(l[1:], l[0] if l[0] < val else val)

l = [34, 23, 2, 4, 18]
print(minimum(l, l[0]))

Output:

2
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
2

In the end, I believe this is just an example on how to iterate through a list using recursion rather than using a loop and used for learning purposes. You can continuously split the list into halves until you get a list of length 1, which is when you surface the element. If you're doing this for learning purposes, I suggest you add print() statements to see what your list is doing.

def minimum(lst):
    if len(lst) == 1:
        return lst[0]
    else:
        m1 = minimum(lst[0:len(lst) / 2])
        m2 = minimum(lst[len(lst) / 2:])
        if m1 < m2:
            return m1
        else:
            return m2


if __name__ == "__main__":
    print(minimum([3, 4, 1, 2, 5]))
    print(minimum([3, 2, 1, 0]))

But as @HFBrowning mentioned in a comment, in real life you should just use min(lst) and be done with it.

And as @PatrickHaugh mentioned in a comment to this answer, the division must return an integer. Which means, if you're running this on Python 3, you should change the len(lst) / 2 to len(lst) // 2 (see the double /?)

Savir
  • 17,568
  • 15
  • 82
  • 136
1
def RecursiveMin(L):
if len(L)==2:
    if L[0]<L[1]:
        return L[0]
    else:
        return L[1]
else:
    X= RecursiveMin(L[1:])
    if L[0]<X:
        return L[0]
    else:
        return X

This formula will give you the smallest value in list.

L=[99,45,78,34,67,2,34,88]
RecursiveMin(L)
>>> 2