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

算法系列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日

相关文章

  • PHP常见数组排序方法小结

    PHP常见数组排序方法小结 PHP的数组是一种非常有用的数据结构。当我们需要对数组进行排序时,PHP提供了许多常见的排序方法,包括冒泡排序、选择排序、插入排序、快速排序等,本文将对这些排序方法进行简要介绍和示例说明。 冒泡排序 冒泡排序是一种常见的排序方法,它的基本思想是:对相邻的元素进行比较,如果顺序不正确就交换。这个过程会持续到整个数组都有序为止。 fu…

    算法与数据结构 2023年5月19日
    00
  • c语言排序之归并排序(递归和非递归)

    下面我来为你详细讲解“C语言排序之归并排序(递归和非递归)”的完整攻略: 什么是归并排序 归并排序是一种基于分治策略的排序算法,其基本思想是将原始数据分成若干个小的子序列,然后将这些小的子序列两两合并成为较大的子序列,直到最终合并成为完整的有序序列。 归并排序可以采用递归和非递归两种方式实现。 归并排序递归实现 归并排序的递归实现相对容易理解,可以通过以下步…

    算法与数据结构 2023年5月19日
    00
  • Js Snowflake(雪花算法)生成随机ID的实现方法

    Js Snowflake(雪花算法)生成随机ID的实现方法 介绍 雪花算法是Twitter开源的一种简单高效、生成唯一ID的算法,可以用于解决数据分布式系统中的ID生成器。本文将介绍使用Js实现雪花算法生成随机ID的完整方法。 实现 引入 首先,我们需要引入雪花算法的js库文件snowflake.js,并在页面中引入 <script src=&quot…

    算法与数据结构 2023年5月19日
    00
  • PHP排序算法之冒泡排序(Bubble Sort)实现方法详解

    PHP排序算法之冒泡排序(Bubble Sort)实现方法详解 冒泡排序概述 冒泡排序是一种基本的排序算法,它的基本思想是比较相邻的两个元素,如果前一个元素比后一个元素大,就交换这两个元素,重复进行这个过程,直到没有任何一对元素需要比较为止。冒泡排序得名于通过交换相邻的元素来把最大值“冒泡”到数列的尽头。 冒泡排序的时间复杂度为O(n²),效率较低,但其思想…

    算法与数据结构 2023年5月19日
    00
  • C语言的冒泡排序和快速排序算法使用实例

    C语言的冒泡排序和快速排序算法使用实例 什么是排序算法 排序算法是一种将一组数据按照特定顺序排列的算法。常见的排序算法包括冒泡排序、快速排序、插入排序、选择排序等。 冒泡排序 冒泡排序是一种简单的排序算法,它重复地走访过要排序的元素,依次比较相邻两个元素,如果它们的顺序错误就交换它们的位置。重复这个过程,直到没有再需要交换的元素,即排序完成。 以下是 C 语…

    算法与数据结构 2023年5月19日
    00
  • C++中的几种排序算法

    下面就C++中几种常用的排序算法进行详细的讲解。 一、冒泡排序 冒泡排序是一种基本排序算法,也是入门级别的排序算法。其基本思想就是对于一组待排序的数据,通过不断地比较相邻两个元素的大小关系,并对需要调整位置的元素进行交换,来达到排序的目的。 C++代码实现: void bubble_sort(int arr[], int n) { for (int i = …

    算法与数据结构 2023年5月19日
    00
  • java冒泡排序简单实例

    下面我来详细讲解一下“Java冒泡排序简单实例”的完整攻略。 简介 冒泡排序是一种简单的排序算法,它重复地走访过要排序的数列,每次比较相邻的两个元素,如果它们的顺序错误就将它们交换过来。重复上述步骤直到整个数列都有序为止。 实现步骤 首先,我们需要定义一个整型数组,用于存储待排序的数据。 int[] array = {5, 3, 8, 6, 4}; 定义一个…

    算法与数据结构 2023年5月19日
    00
  • c#实现选择排序的示例

    C#实现选择排序主要包含以下步骤: 定义数组 遍历数组,选出最小元素,并记录其索引 交换当前索引和最小值索引的元素 循环执行步骤2和步骤3,直到整个数组排序完成 以下是实现选择排序的C#示例: 示例1: int[] arr = new int[]{5, 3, 9, 1, 7, 4}; for (int i = 0; i <arr.Length; i++…

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