【数据结构与算法Python版学习笔记】查找与排序——查找:顺序查找与二分查找

顺序查找

定义

  • 通过下标, 按照顺序来访问和查找数据项
  • 要确定列表中是否存在需要查找的数据项

算法分析

要点

  • 确定基本计算步骤
  • 基本计算步骤必须要足够简单, 并且在算法中反复执行
  • 在查找算法中, 这种基本计算步骤就是进行数据项的比对,比对的次数决定了算法复杂度

分类

  • 无序列表顺序查找O(n)
    • 数据在列表中,平均比对次数$n\over2$
    • 数据不在列表中,平均比对次数n
  • 有序列表顺序查找O(n)
    • 数据在列表中,平均比对次数$n\over2$
    • 数据项不存在的时候, 有序表的查找能节省一些比对次数, 但并不改变其数量级,平均比对次数n

代码

  • 无序列表顺序查找
# 查找
def sequentialSearch(alist, item):
    pos = 0
    found = False
    while pos < len(alist) and not found:
        if alist[pos] == item:
            found = True
        else:
            pos += 1
    return found

if __name__ == "__main__":
    testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]
    print(sequentialSearch(testlist, 3))
    print(sequentialSearch(testlist, 13))
  • 有序列表顺序查找
def orederedSequentialSearch(alist, item):
    pos = 0
    found = False
    stop=False
    while pos < len(alist) and not found and not stop:
        if alist[pos] == item:
            found = True
        elif alist[pos] > item:
            stop=True
        else:
            pos += 1
    return found,pos

if __name__ == "__main__":
    testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]
    testlist.sort()
    print(orederedSequentialSearch(testlist, 3))
    print(orederedSequentialSearch(testlist, 13))

二分查找

定义

  • 利用有序表的特性
  • 从列表中间开始比对,每次都会将比对范围缩小一半

算法分析

  • 复杂度Log(n)
  • 使用了列表切片,切片操作复杂度O(k),可以不使用,只传入起始和结束的索引值
  • 需要考虑到对数据项进行排序的开销
  • 所以, 在算法选择的问题上, 光看时间复杂度的优劣是不够的, 还需要考虑到实际应用的情况。

代码

  • 普通
def binarySearch(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
        else:
            if item < alist[midpoint]:
                last = midpoint-1
            else:
                first = midpoint+1
    return found

if __name__ == "__main__":
    testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]
    testlist.sort()
    print(binarySearch(testlist, 3))
    print(binarySearch(testlist, 13))
  • 分治递归解法
def binarySearch2(alist, item):
    if len(alist) ==0 :
        return False
    else:
        midpoint = len(alist)//2
        if alist[midpoint] == item:
            return True
        else:
            if alist[midpoint] < item:
                return binarySearch(alist[:midpoint],item)
            else:
                return binarySearch(alist[midpoint+1:],item)

if __name__ == "__main__":
    testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]
    testlist.sort()
    print(binarySearch2(testlist, 3))
    print(binarySearch2(testlist, 13))
posted @ 2021-04-22 13:41  砥才人  阅读(192)  评论(0编辑  收藏  举报