算法系列15天速成 第六天 五大经典查找【下】

yizhihongxing

算法系列15天速成 第六天 五大经典查找【下】- 完整攻略

简介

本篇文章是算法系列15天速成中的第六天内容,主要是介绍五大经典查找的后三种查找算法:插值查找、斐波那契查找以及分块查找。在介绍每一种查找算法时都会包含具体的思路、复杂度和应用场景等内容。

插值查找

思路

插值查找是在二分查找的基础上优化的一种查找算法,它不是通过数组的中间元素进行查找,而是通过插值公式计算出要查找的元素的位置。插值公式如下:

mid = left + (right-left)*(value-arr[left])/(arr[right]-arr[left])

其中value是要查找的元素,arr是已排序的数组。

复杂度

插值查找算法的时间复杂度为O(log n),在特定的情况下,它可以具有比二分查找更高的效率。

应用场景

插值查找可以用于均匀分布的有序数组中。

示例

# 插值查找实现
def interpolation_search(arr, value):
    left, right = 0, len(arr) - 1

    while left <= right and value >= arr[left] and value <= arr[right]:

        mid = left + (right-left)*(value-arr[left])//(arr[right]-arr[left])

        if arr[mid] == value:
            return mid

        elif arr[mid] < value:
            left = mid + 1

        else:
            right = mid - 1

    return -1

# 测试插值查找
arr = [1, 3, 5, 7, 9, 11]
value = 5
print(interpolation_search(arr, value))

斐波那契查找

思路

斐波那契查找是对插值查找算法的进一步优化,它使用斐波那契数列的值来计算要查找的值在数组中的位置。具体来说,要查找的值value在第n个斐波那契数列中出现,使用斐波那契数列的前两个值F(k)F(k-1)来计算要查找的值在数组中的位置。具体过程可以参考:https://www.cnblogs.com/maybe2030/p/4715035.html

复杂度

斐波那契查找算法的时间复杂度为O(log n)。

应用场景

斐波那契查找可以用于有序数组中。

示例

# 斐波那契查找实现
def fibonacci_search(arr, value):
    left, right = 0, len(arr) - 1

    # 构建斐波那契数列
    fib = [0, 1, 1]
    while fib[-1] < len(arr):
        fib.append(fib[-1] + fib[-2])

    # 在斐波那契数列中寻找 value 对应的位置
    k = 0
    while fib[k+1] < len(arr):
        k += 1
    offset = fib[k-1]
    while True:
        if value > arr[right]:
            return -1
        if value < arr[left]:
            return -1
        if left > right:
            return -1

        mid = left + offset
        if value < arr[mid]:
            right = mid - 1
            offset = offset - fib[k-2]
            k -= 1
        elif value > arr[mid]:
            left = mid + 1
            offset = offset - fib[k-1]
            k -= 2
        else:
            return mid

分块查找

思路

分块查找是一种数据分块技术,它将一个大的数据集分割成若干块,并且每一块的数据是有序的,块与块之间的数据无序,这样做的目的是使得查找的复杂度降低。

复杂度

分块查找算法的时间复杂度为O(sqrt(n)),空间复杂度为O(n)。

应用场景

分块查找可以用于难以排序的大规模数据中。

示例

# 分块查找实现
from math import sqrt, ceil

def block_search(arr, value):
    n = len(arr)                          # 数据集大小
    block_size = ceil(sqrt(n))            # 计算分块块长
    block_num = ceil(n / block_size)      # 计算分块数量

    # 计算块的范围,预处理数据块
    blocks = []
    for i in range(block_num):
        left = i * block_size 
        right = min(left + block_size, n)
        blocks.append({'left': left, 'right': right, 'data': arr[left:right]})

    # 在块内二分查找
    target_block = -1
    for i in range(block_num):
        if arr[blocks[i]['left']] <= value <= arr[blocks[i]['right']-1]:
            target_block = i
            break
    if target_block == -1:
        return -1
    else:
        target_index = binary_search(blocks[target_block]['data'], value)
        return blocks[target_block]['left'] + target_index

# 二分查找
def binary_search(arr, value):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == value:
            return mid
        elif arr[mid] < value:
            left = mid + 1
        else:
            right = mid - 1
    return -1

# 测试分块查找
arr = [5, 2, 7, 9, 1, 3, 11, 6, 8, 4, 12, 10]
value = 10
print(block_search(arr, value))

总结

本文介绍了插值查找、斐波那契查找和分块查找算法,这三种查找算法都是在二分查找的基础上进行的优化,分别针对了不同的场景和数据特点进行了优化。这些算法适用的场景也不尽相同,需要根据具体情况选择适合的算法进行使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:算法系列15天速成 第六天 五大经典查找【下】 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • C++实现位图排序实例

    C++实现位图排序实例攻略 什么是位图排序 位图排序是一种空间换时间的算法,主要针对大量重复性数据的排序问题。其主要思想是将待排序的数据作为位图的索引,将出现的数据标识为1,最后按照位图的索引顺序输出结果。 如何实现位图排序 具体实现步骤如下: 确定位图最大数据值及位图长度。假设需要排序的数据范围是[1,10000],对应的位图长度为(10000/8)+1=…

    算法与数据结构 2023年5月19日
    00
  • TypeScript十大排序算法插入排序实现示例详解

    针对“TypeScript十大排序算法插入排序实现示例详解”的完整攻略,我有如下的描述和示例: 1. 算法简介 插入排序(Insertion Sort)是一种简单直观的排序算法。它的基本思想是将目标数组分为已排序和未排序区间,每次从未排序区间中选取一个元素并插入到已排序区间中正确的位置。 插入排序是一种相对基础的排序算法,不仅实现起来比较简单,而且时间复杂度…

    算法与数据结构 2023年5月19日
    00
  • 排序算法图解之Java插入排序

    首先要了解什么是插入排序,插入排序是排序算法中简单直观的一种,其原理是将未排序的元素一个一个插入到已经排好序的元素中,最终得到一个有序的序列。那么下面我将用Java代码来演示插入排序的实现过程,并且提供详细的注释帮助读者理解。 算法步骤 从第一个元素开始,认为第一个元素是已经排好序的,取第二个元素和已排序的元素进行比较,如果第二个元素比已排序的元素小,则交换…

    算法与数据结构 2023年5月19日
    00
  • 详解C++实现链表的排序算法

    详解C++实现链表的排序算法 算法介绍 链表是一种常见的数据结构,在实际使用中常常需要对链表进行排序。本文将介绍在C++中实现链表排序的几种算法,包括插入排序,归并排序和快速排序。 插入排序 插入排序(Insertion Sort)是一种简单直观的排序算法。具体实现过程如下: 遍历链表,取下一个节点作为插入节点。 如果当前节点不小于插入节点,则将插入节点插入…

    算法与数据结构 2023年5月19日
    00
  • PHP冒泡排序算法代码详细解读

    PHP冒泡排序算法代码详细解读 什么是冒泡排序? 冒泡排序是一种简单的排序算法,通过交换相邻元素比较和交换的方式进行排序。该算法会重复遍历待排序的数列,每次比较相邻的两个元素,如果顺序错误就交换位置。重复执行这个过程,直到整个数列有序。 算法实现过程 以下是基于PHP语言实现的冒泡排序代码,对应的注释为算法的实现过程说明。 function bubbleSo…

    算法与数据结构 2023年5月19日
    00
  • Go语言展现快速排序算法全过程的思路及代码示例

    这里是关于“Go语言展现快速排序算法全过程的思路及代码示例”的详细攻略。 什么是快速排序算法 快速排序算法是一种基于比较的排序算法,它通过选择一个基准元素,将数组分为两部分然后递归地对这两部分进行排序,最终完成对整个数组的排序。快速排序算法的时间复杂度为 O(nlogn) 平均情况下,但是在最坏情况下会退化为 O(n^2)。 快速排序算法的实现思路 下面是快…

    算法与数据结构 2023年5月19日
    00
  • c语言实现基数排序解析及代码示例

    c语言实现基数排序解析及代码示例 前言 基数排序是一种特殊的排序算法,它的时间复杂度为O(dn),其中d表示数据位数,n表示数据个数。它可以用于排序整数、字符串、链表等数据类型。本篇攻略通过讲解基数排序的原理、流程和C语言实现,希望能够帮助大家更好地理解和应用基数排序算法。 基数排序原理 基数排序是一种非比较排序算法,它的实现基于按照键值的每位数字对待排序数…

    算法与数据结构 2023年5月19日
    00
  • PHP排序算法之快速排序(Quick Sort)及其优化算法详解

    PHP排序算法之快速排序(Quick Sort)及其优化算法详解 快速排序是一种高效的排序算法,也是PHP中常用的排序方法之一。在本攻略中,我们将介绍快速排序的基本思想与原理,以及一些优化算法和实际示例。 快速排序基本原理 快速排序的基本思想是:通过一趟排序将待排序记录分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据小,然后再按此方法对这两部…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部