七大查找算法之有序表查找---二分查找

二分查找

      二分查找也称为是折半查找,属于有序查找算法。元素必须是有序的,如果是无序的则要先进行排序操作。二分查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,二分查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。

原理:

       二分查找用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。

算法详细描述:

  • 选择一个可以将列表arr大致一份为二的索引i;
  • 检查是否有arr[i] == target;
  • 如果不是,检查arr[i]大于还是小于target;
  • 根据上一步的结果,确定在arr的左半部分还是右半部分搜索target。

代码实现:

## 递归版本
def binarySearch(arr, target):
    """
    假设arr是列表,其中元素按升序排列.
    如果target是arr中的元素,则返回True,否则返回False
    """

    def bSearch(arr, target, low, high):
        if high == low:
            return arr[low] == target
        mid = (low + high) // 2
        if arr[mid] == target:
            return True
        elif arr[mid] > target:
            if low == mid:
                return False
            else:
                return bSearch(arr, target, low, mid - 1)
        else:
            return bSearch(arr, target, mid + 1, high)

    if len(arr) == 0:
        return False
    else:
        return bSearch(arr, target, 0, len(arr) - 1)

## 非递归版本
def binarySearch(arr, target):
    low = 0
    high = len(arr) - 1
    while low < high:
        mid = (low + high) // 2
        if target < arr[mid]:
            high = mid - 1
        elif target > arr[mid]:
            low = mid + 1
        else:
            return True
    return False

时间复杂度:

       假设,总共有n个元素,每次查找的区间大小就是n,n/2,n/4,…,n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数。由于n/2^k取整后>=1,即令n/2^k=1,可得k=log2n,(是以2为底,n的对数),所以时间复杂度可以表示O()=O(logn)

猜你喜欢

转载自blog.csdn.net/qq_30123335/article/details/83239561