Binary search algorithm in python

前端 未结 14 927
别那么骄傲
别那么骄傲 2020-12-01 11:23

I am trying to implement the binary search in python and have written it as follows. However, I can\'t make it stop whenever needle_element is larger than the largest elemen

相关标签:
14条回答
  • 2020-12-01 11:33

    Without the lower/upper indexes this should also do:

    def exists_element(element, array):
        if not array:
            yield False
    
        mid = len(array) // 2
        if element == array[mid]:
            yield True
        elif element < array[mid]:
            yield from exists_element(element, array[:mid])
        else:
            yield from exists_element(element, array[mid + 1:])
    
    0 讨论(0)
  • 2020-12-01 11:35

    This is a tail recursive solution, I think this is cleaner than copying partial arrays and then keeping track of the indexes for returning:

    def binarySearch(elem, arr):
        # return the index at which elem lies, or return false
        # if elem is not found
        # pre: array must be sorted
        return binarySearchHelper(elem, arr, 0, len(arr) - 1)
    
    def binarySearchHelper(elem, arr, start, end):
        if start > end:
            return False
        mid = (start + end)//2
        if arr[mid] == elem:
            return mid
        elif arr[mid] > elem:
            # recurse to the left of mid
            return binarySearchHelper(elem, arr, start, mid - 1)
        else:
            # recurse to the right of mid
            return binarySearchHelper(elem, arr, mid + 1, end)
    
    0 讨论(0)
  • 2020-12-01 11:38

    It would be much better to work with a lower and upper indexes as Lasse V. Karlsen was suggesting in a comment to the question.

    This would be the code:

    def binary_search(array, target):
        lower = 0
        upper = len(array)
        while lower < upper:   # use < instead of <=
            x = lower + (upper - lower) // 2
            val = array[x]
            if target == val:
                return x
            elif target > val:
                if lower == x:   # these two are the actual lines
                    break        # you're looking for
                lower = x
            elif target < val:
                upper = x
    
    • lower < upper will stop once you have reached the smaller number (from the left side)
    • if lower == x: break will stop once you've reached the higher number (from the right side)

    Example:

    >>> binary_search([1,5,8,10], 5)   # return 1
    1
    >>> binary_search([1,5,8,10], 0)   # return None
    >>> binary_search([1,5,8,10], 15)  # return None
    
    0 讨论(0)
  • 2020-12-01 11:41

    Using Recursion:

    def binarySearch(arr,item):
        c = len(arr)//2
        if item > arr[c]:
           ans = binarySearch(arr[c+1:],item)
           if ans:
              return binarySearch(arr[c+1],item)+c+1
        elif item < arr[c]:
           return binarySearch(arr[:c],item)
        else:
           return c
    
    binarySearch([1,5,8,10,20,50,60],10)
    
    0 讨论(0)
  • 2020-12-01 11:41

    Returning a boolean if the value is in the list.

    Capture the first and last index of the list, loop and divide the list capturing the mid value. In each loop will do the same, then compare if value input is equal to mid value.

    def binarySearch(array, value):
      array = sorted(array)
      first = 0
      last = len(array) - 1
    
      while first <= last:
        midIndex = (first + last) // 2
        midValue = array[midIndex]
    
        if value == midValue:
          return True
        if value < midValue:
          last = midIndex - 1
        if value > midValue:
          first = midIndex + 1
      return False
    
    0 讨论(0)
  • 2020-12-01 11:43

    You can improve your algorithm as the others suggested, but let's first look at why it doesn't work:

    You're getting stuck in a loop because if needle_element > array[mid], you're including element mid in the bisected array you search next. So if needle is not in the array, you'll eventually be searching an array of length one forever. Pass array[mid+1:] instead (it's legal even if mid+1 is not a valid index), and you'll eventually call your function with an array of length zero. So len(array) == 0 means "not found", not an error. Handle it appropriately.

    0 讨论(0)
提交回复
热议问题