查找算法

先分享一波好物

基于线性表的查找算法

(1)顺序查找算法

  • 用数组存储
  • 按顺序查找关键字的位置
def seq_search(l,a):
    l.index(a)
    for i , k in enumerate(l):
        if k==a:
            return i
    return -1
L=[2 ,5,2,6,8,6]
seq_search(L,3)

此代码与下代码同作用

L.index(5)

(2)折半查找算法

与折半插入排序算法思想差不多:

只能在有序的数组中查找

设给定的数组为A,元素为A[i],元素个数一共有n个,其中0<=i<=n-1

  1. 分别指向数列的第一位和末位,下标为low和highm = (low + high)/2
  2. 如果要插入的数小于m位置的数,说明要在低半区查找,high = m - 1
  3. 如果要插入的数大于m位置的数,说明要在高半区查找,low = m + 1
  4. 如果要插入的数等于m位置的数,直接退出,high=m
def halffind(l,a):
    low = 0
    high = len(l) - 1
    mid = (low + high) // 2
    while low <= high:
        if l[mid] > a:
            high = mid - 1
        elif l[mid] < a:
            low = mid + 1
        else:
            return mid
        mid = (low + high) // 2
    return -1

(3)插值查找算法
在折半查找的基础上多了:

  • mid= (key-a[low])/(a[high]-a[low])*(high-low)
# 作者:沙振宇
# 时间复杂性:如果元素均匀分布,则O(log log n)),在最坏的情况下可能需要 O(n)。
# 空间复杂度:O(1)。

# 插值查找算法
def interpolation_search(list, key):
    length = len(list)
    low = 0
    high = length - 1
    time = 0
    print("length:%s list:%s"%(length,list))
    while low < high:
        time += 1
        # 计算mid值是插值算法的核心代码
        mid = low + int((high - low) * (key - list[low]) / (list[high] - list[low]))
        if key < list[mid]:
            high = mid - 1
        elif key > list[mid]:
            low = mid + 1
        else:
            return mid
    return False

if __name__ == '__main__':
    list = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
    result = interpolation_search(list, 444)
    print("List key is:", result)

(4)分块查找算法
分块算法是在顺序查找法中的一个优化,基于一个已排序好的数组中做的查找。

  • 时间复杂度:O(log(m)+N/m)
  1. 先选取各块中的最大关键字构成一个索引表
  2. 查找分两个部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中
  3. 在已确定的块中用顺序法进行查找



# 二分查找
def binary_search(list, key):
    length = len(list)
    first = 0
    last = length - 1
    print("length:%s list:%s"%(length,list))
    while first <= last:
        mid = (last + first) // 2
        if list[mid] > key:
            last = mid - 1
        elif list[mid] < key:
            first = mid + 1
        else:
            return mid
    return False

# 分块查找
def block_search(list, count, key):
    length = len(list)
    #############分块思想,分block_length个块分数据############
    block_length = length//count
    if count * block_length != length:
        block_length += 1
    print("block_length:", block_length) # 块的多少
    for block_i in range(block_length):
        block_list = []
        for i in range(count):
            if block_i*count + i >= length:
                break
            block_list.append(list[block_i*count + i])
    #######################################################
        result = binary_search(block_list, key)
        if result != False:
            return block_i*count + result
    return False

if __name__ == '__main__':
    list = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
    result = block_search(list, 4, 444) # 第二个参数是块的长度,最后一个参数是要查找的元素
    print("List key is:", result)

基于树的查找法

(1)二叉排序树(BST)

终于可以贴自己的好物分享啦

(2)二叉平衡树

好物分享

斐波那契查找法

斐波那契查找就是在二分查找的基础上根据斐波那契数列进行分割的:

  1. 在斐波那契数列找一个等于略大于查找表中元素个数的数F[n],将原查找表扩展为长度为F[n](如果要补充元素;
  2. 则补充重复最后一个元素,直到满足F[n]个元素),完成后进行斐波那契分割,即F[n]个元素分割为前半部分F[n-1]个元素;
  3. 后半部分F[n-2]个元素,找出要查找的元素在那一部分并递归,直到找到。
# 斐波那契查找算法
def fibonacci_search(list, key):
    length = len(list)
    # 需要一个现成的斐波那契列表。其最大元素的值必须超过查找表中元素个数的数值。
    F = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368]
    low = 0
    high = length - 1
    print("length:%s list:%s"%(length,list))

    # 为了使得查找表满足斐波那契特性,在表的最后添加几个同样的值
    # 这个值是原查找表的最后那个元素的值
    # 添加的个数由F[k]-1-high决定
    k = 0
     #找一个比数组长度大一点的元素
    while high > F[k] - 1:
        k += 1
    i = high
   ##往数组后面添元素直到长度为F[k]-1,添加的都是数组最后一个元素
    while F[k] - 1 > i:
        list.append(list[high])
        i += 1
    time = 0 # 算法主逻辑。time用于展示循环的次数。
    while low <= high:
        time += 1
        # 为了防止F列表下标溢出,设置if和else
        if k < 2:
            mid = low
        else:
            mid = low + F[k - 1] - 1
        if key < list[mid]:
            high = mid - 1
            k -= 1
        elif key > list[mid]:
            low = mid + 1
            k -= 2
        else:
            if mid <= high:
                return mid
            else:
                return high
    return False

if __name__ == '__main__':
    list = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
    result = fibonacci_search(list, 7)
    print("List key is:", result)

高级数表查找算法

红黑树
B、B+树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值