数据结构和算法-二分查找

本篇主要是< <数据结构和算法-王争> >教程笔记和python实现 python

原理: 在一个有序数组中, 不断比较中间位置的数和目标数的大小, 若是中间位置数比目标数大, 则再用一样办法比较前半部分, 不然比较后半部分. 若是没有找到目标数的位置, 返回None, 不然返回该数的位置. 由于是不断把数组分为一半一半的找, 因此时间复杂度是O(logn).算法

时间复杂度: O(logn)数组

实现

注: 要注意边界状况数据结构

# coding:utf-8

def binary_search(nums, value):
    low = 0
    high = len(nums) - 1
    # 注意是 <=
    while low <= high:
        mid = int((low + high) / 2)
        mid_value = nums[mid]
        # 注意 low 和 high 的取值, 防止发生死循环. 好比low=3, high=3
        if mid_value < value:
            low = mid + 1
        elif mid_value > value:
            high = mid - 1
        else:
            return mid
    return -1


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

注意点:数据结构和算法

  • 边界状况, 特别注意注释内容, 防止发生死循环
  • mid = int((low + high) / 2)可能发生整数溢出, 能够优化改成
mid = low + int((high-low)/2)
# 或
low + int((high - low) >> 1)   # 位运算

缺点:优化

  • 依赖数组, 不能是链表
    数据量太大不适合. 由于依赖数组, 因此必需要求内存是连续的, 好比须要连续的1G空间. 如今有2G不连续的内存也没有办法使用
  • 数组必须有序
    若是数组常常插入/删除, 每次都须要排序, 则不适合二分查找

二分查找变形问题

通常状况下能用二分查找解决的问题也可使用二叉查找树和散列表来解决, 可是二分查找适合如下问题code

如下状况容许出现重复元素排序

1. 查找第一个值 = 给定值的元素

# coding:utf-8

"""
查找数组中第一个=给定值的元素, 返回索引位置
"""


def binary_search(nums, value):
    low = 0
    high = len(nums) - 1
    while low <= high:
        mid = low + ((high - low) >> 1)
        mid_value = nums[mid]
        if mid_value < value:
            low = mid + 1
        elif mid_value > value:
            high = mid - 1
        else:
            if mid == 0 or nums[mid - 1] != value:
                return mid
            else:
                high = mid - 1

    return -1


if __name__ == "__main__":
    nums = [1, 3, 4, 5, 6, 8, 8, 8, 11, 18]
    print(binary_search(nums, 8))

2. 查找最后一个值 = 给定值的元素

def binary_search_2(nums, value):
    """
    查找数组中最后一个等于给定值的元素, 返回索引位置
    """
    low = 0
    high = len(nums) - 1
    last_pos = high
    while low <= high:
        mid = low + ((high - low) >> 1)
        mid_value = nums[mid]
        if mid_value < value:
            low = mid + 1
        elif mid_value > value:
            high = mid - 1
        else:
            # 若是mid==最后一位, 那么是第一个元素确定是要找的值
            if mid == last_pos or nums[mid + 1] != value:
                return mid
            else:
                # 要找的值确定在mid+1和high之间
                low = mid + 1

    return -1

3. 查找第一个 >= 给定值的元素

def binary_search_3(nums, value):
    """
    查找数组中第一个 >= 给定值的元素, 返回索引位置
    """
    low = 0
    high = len(nums) - 1
    while low <= high:
        mid = low + ((high - low) >> 1)
        mid_value = nums[mid]

        if mid_value >= value:
            if mid == 0 or nums[mid - 1] < value:
                return mid
            else:
                high = mid - 1
        else:
            low = mid + 1

    return -1

4. 查找最后一个 <= 给定值的元素

def binary_search_4(nums, value):
    """
    查找数组中最后一个 <= 给定值的元素, 返回索引位置
    """
    low = 0
    high = len(nums) - 1
    last_pos = high

    while low <= high:
        mid = low + ((high - low) >> 1)
        mid_value = nums[mid]

        if mid_value > value:
            high = mid - 1
        else:
            if mid == last_pos or nums[mid + 1] > value:
                return mid
            else:
                low = mid + 1

    return -1

资料

  • < <数据结构和算法> > - 王争
  • < <大话数据结构> >

相关文章
相关标签/搜索