【算法】Python有序列表的二分法查找

二分法查找的思路

先确定好列表nums的左边 left, 右边right,
中间值mid 根据左边加上 右边减去左边的差除以2,即 left+ (right left) / 2。这种写法在Java中可以避免越界
将目标值target与nums[mid]进行比对,这时候有3种结果:
nums[middle] > target
nums[middle] < target
nums[middle] = target
以上3种情况前2种不断循环,直到满足第3种跳出循环。

# coding = utf-8
"""
在一个有序序列中找到指定元素,若找到返回其在数列中的位置,若没找到返回-1
"""


def binary_search(list1, k):
    """
    二分(折半)查找
    :param list1:
    :param k:
    :return:
    """
    if list1 is None:
        return -1
    left = 0
    right = len(list1) - 1
    while left <= right:
        mid = left + ((right - left) >> 1)
        # 如果中间值 > 目标值,将右边界左移
        if list1[mid] > k:
            right = mid - 1
        # 如果中间值 < 目标值,将左边界右移
        elif list1[mid] < k:
            left = list1[mid] + 1
        else:
            return mid
    return -1


def binary_search2(list1, left, right, k):
    """
    递归版二分查找
    :param list1:
    :param left:
    :param right:
    :param k:
    :return:
    """
    # 区间上只有一个数
    if left == right:
        return left if list1[left] == k else -1
    # 划分区间
    mid = (right + left) >> 1
    # 如果中间值> 目标值,在左半边继续查找
    if list1[mid] > k:
        return binary_search2(list1, left, mid - 1, k)
    # 如果中间值 < 目标值,在右半边继续查找
    elif list1[mid] < k:
        return binary_search2(list1, mid + 1, right, k)
    else:
        return mid


if __name__ == '__main__':
    list1 = [1, 2, 3, 4, 8, 9, 10, 11]
    k = 9
    ret = binary_search(list1, k)
    print(ret)

    ret2 = binary_search2(list1, 0, len(list1) - 1, k)
    print(ret2)

猜你喜欢

转载自blog.csdn.net/chichu261/article/details/84328450