python数据结构【1】--二分查找

前言:查找可以说是我们代码里用得比较多的操作,比如我们经常需要在一个列表里找到我们需要的一个元素,然后返回它的位置。 其实哈希表就是非常高效率的查找数据结构,很明显地它是用空间换时间。这一节介绍两个基本的基于线性结构的查找。


不过在讲二分查找之前,我们先谈谈算法的时间复杂度和空间复杂度

1、复杂度

1.1时间复杂度

       1)时间复杂度是用来估计算法运行时间的一个式子(单位)。

       2)常见的时间复杂度(按效率排序)

              O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)

       3)如何一眼判断时间复杂度?

1.2空间复杂度 

  • 循环减半的过程 --O(logn)
  • 几次循环就是n的几次方的复杂度

空间复杂度:用来评估算法内存占用大小的一个式子

“空间换时间”

2、列表查找

列表查找:从列表中查找指定元素

  • 输入:列表、待查找元素
  • 输出:元素下标或未查找到元素

其中这里介绍的列表查找方法有线性查找和二分查找

2.1 线性查找

线性查找就是从头找到尾,直到符合条件了就返回。比如在一个 list 中找到一个等于 5 的元素并返回下标:

number_list = [0, 1, 2, 3, 4, 5, 6, 7]

def linear_search(value, iterable):
    for index, val in enumerate(iterable):
        if val == value:
            return index
    return -1

assert linear_search(5, number_list) == 5

2.2 二分查找

       上一小节说的线性查找针对的是无序序列,假如一个序列已经有序了呢,我们还需要从头找到尾吗?当然不用,折半(二分)是一种经典思想。

有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半。

思路:

  1. 在一段区间内,找到中间位置的值 
  2. 比较要查找的值与中间位置值的大小,若相等,则返回,若不相等:如果中间值大一点,则下一步候选区域变为左区域,如果中间值大一点,则下一步候选区域变为右区域。 
  3. 如此重复,直到找到要查找的数字。

def binary_search(sorted_array, val):
    if not sorted_array:
        return -1
    low = 0
    high = len(sorted_array) - 1

    while low <= high:
        mid = int((low + high) / 2)  # 为了屏蔽 python 2/3 差异我用了强转
        #mid = (low+high)//2       或者使用这种方式,也是可行的
        if sorted_array[mid] == val:
            return mid
        elif sorted_array[mid] > val:
            high = mid - 1
        else:
            low = mid + 1
    return -1    #未找到,返回为-1

def test_binary_search():
    a = list(range(10))
    # 正常值
    assert binary_search(a, 1) == 1
    assert binary_search(a, -1) == -1
    # 异常值
    assert binary_search(None, 1) == -1
    # 边界值
    assert binary_search(a, 0) == 0

猜你喜欢

转载自blog.csdn.net/qq_20412595/article/details/82494119