数据结构与算法学习笔记——查找Search

顺序查找及算法分析(Sequential Search):

如果数据项保存在如列表这样的集合中,我们回陈这些数据想具有线性或者顺序关系。

例如在python list中,这些数据项的存储位置陈伟下标,这些下标都是有序的整数。 通过下标,我们就可以按照顺序来访问和查找数据项。 这些技术成为”顺序查找“

 

要确定列表中是否存在需要查找到数据项:

首先要从列表的第一个数据项开始,按照下标增长的顺序,逐个对比数据项,

如果到最后一个都未发现要查找的项,那么查找失败。

def sequentialSearch (alist,item):
    
    pos = 0
    found = False
    
    while pos< len(alist):
        if alist[pos] == item:
            found = True
        else:
            pos += 1
    return found

当输入的数组是无序(每个元素出现在每个位置的概率是相同的情况下):计算(对比)的次数也是不一样的。

但无论数组是有序的还是无序的,算法的复杂都都是不变的(O(n)),因为它们在计算的数量级上是没有变化的。

 

二分查找算法及分析(Binary Search):

对于有序表,如果按照顺序查找的方法,倘若第一个数据项不匹配查找想的话,那么最多还有n-1个待对比的数据项。

但是,如果从列表的中间开始比对,则会出现两种情况:

1. 列表中间项比查找项大,那么查找项只可能出现在前半部分

2. 列表中间项比查找项小,那么查找项只可能出现在后半部分

但无论如何,对比的范围都缩小到了原来的一般.

Python实现:

def binary_search(alist,item):
    first = 0
    last = len(alist)-1
    found = False
    
    while first < last and not found: 
        midPoint = (first + last) // 2
        if alist[midPoint] == item:
            found  = True
        elif alist[midPoint] > item:
            last = midPoint -1
        else: first = midPoint + 1
    return found

 

二分法体现了一种典型策略:分而治之

即将问题分为若干个更小规模的部分,这于递归的特点也很相似。所以二分法也适用递归算法来实现:

def binary_search_recursion(alist,item):
    if len(alist) == 0:
        return False

    midpoint = len(alist)//2
    if alist[midpoint] == item:
        return True
    else:
        if alist[midpoint] > item:
            return binary_search_recursion(alist[0:midpoint],item)
        elif alist[midpoint] < item:
            return binary_search_recursion(alist[midpoint+1:],item)

print(binary_search_recursion([1,2,3,4,5],5))

由于而二分查找每次都会将下一步的比对范围缩小一半, 当对比次数足够多以后,比对范围就会仅剩余1个数据项。

即若数据项的个数为n,经过x次后可以缩小至范围为。

2^x = N    =>     x = log2(N)

所以算法复杂度为O(log N)

 

还有一个因素需要注意:

binarySearch(alist[:midpoint],item) 这个递归调用使用了列表切片,而且pain操作的复杂度是O(K),这样会使得整个算法的时间复杂度稍有增加;

如果要减少这个时间开销,可以传入其实和结束的索引

 

另外,虽然二分查找在时间复杂度上优于顺序查找,但也要考虑到对数据项进行排序的开销。如果依次排序后就可以进行多次查找,那么排序的开销就可以摊薄。但如果数据集经常变动,查找次数相对较少,那么可能还是直接用无序表叫上顺序查找来得经济。 

所以在算法的选择问题上,光看时间复杂度的优劣是不够的,还需要考虑到实际应用的情况。

 

posted on 2022-09-06 22:09  无甲的乔  阅读(91)  评论(0)    收藏  举报