顺序、二分、插值、斐波那契查找算法

常用的查找算法有顺序查找,二分查找(折半查找),插值查找,斐波那契查找,下面我把每一种都举个例子。

1. 顺序查找(线性查找)

顺序查找是最简单的查找算法,它逐个比较数组中的元素,直到找到目标元素或遍历完数组。

cpp 复制代码
#include <stdio.h>
// 顺序查找函数
int sequentialSearch(int arr[], int size, int target) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == target) {
            return i; // 找到目标,返回索引
        }
    }
    return -1; // 未找到目标
}
int main() {
    int arr[] = {12, 34, 54, 2, 3};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 2;

    int result = sequentialSearch(arr, size, target);

    if (result != -1) {
        printf("元素 %d 在索引 %d 处找到\n", target, result);
    } else {
        printf("元素 %d 未找到\n", target);
    }

    return 0;
}

2. 二分查找(折半查找)

二分查找要求数组是有序的,它通过不断将查找范围缩小一半来找到目标元素。

cpp 复制代码
#include <stdio.h>
// 二分查找函数(递归实现)
int binarySearchRecursive(int arr[], int left, int right, int target) {
    if (left <= right) {
        int mid = left + (right - left) / 2; // 防止溢出

        if (arr[mid] == target) {
            return mid; // 找到目标,返回索引
        } else if (arr[mid] < target) {
            return binarySearchRecursive(arr, mid + 1, right, target); // 在右半部分查找
        } else {
            return binarySearchRecursive(arr, left, mid - 1, target); // 在左半部分查找
        }
    }
    return -1; // 未找到目标
}
// 二分查找函数(迭代实现)
int binarySearchIterative(int arr[], int size, int target) {
    int left = 0;
    int right = size - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;

        if (arr[mid] == target) {
            return mid; // 找到目标,返回索引
        } else if (arr[mid] < target) {
            left = mid + 1; // 在右半部分查找
        } else {
            right = mid - 1; // 在左半部分查找
        }
    }
    return -1; // 未找到目标
}
int main() {
    int arr[] = {2, 3, 12, 34, 54};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 34;

    int resultRecursive = binarySearchRecursive(arr, 0, size - 1, target);
    int resultIterative = binarySearchIterative(arr, size, target);

    if (resultRecursive != -1) {
        printf("递归实现:元素 %d 在索引 %d 处找到\n", target, resultRecursive);
    } else {
        printf("递归实现:元素 %d 未找到\n", target);
    }

    if (resultIterative != -1) {
        printf("迭代实现:元素 %d 在索引 %d 处找到\n", target, resultIterative);
    } else {
        printf("迭代实现:元素 %d 未找到\n", target);
    }

    return 0;
}

3. 插值查找

插值查找是二分查找的改进版本,它根据目标元素的位置动态调整查找点,适用于均匀分布的有序数组。

cpp 复制代码
#include <stdio.h>
// 插值查找函数
int interpolationSearch(int arr[], int size, int target) {
    int left = 0;
    int right = size - 1;

    while (left <= right && target >= arr[left] && target <= arr[right]) {
        // 计算插值位置
        int pos = left + ((target - arr[left]) * (right - left)) / (arr[right] - arr[left]);

        if (arr[pos] == target) {
            return pos; // 找到目标,返回索引
        } else if (arr[pos] < target) {
            left = pos + 1; // 在右半部分查找
        } else {
            right = pos - 1; // 在左半部分查找
        }
    }
    return -1; // 未找到目标
}
int main() {
    int arr[] = {10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 18;

    int result = interpolationSearch(arr, size, target);

    if (result != -1) {
        printf("元素 %d 在索引 %d 处找到\n", target, result);
    } else {
        printf("元素 %d 未找到\n", target);
    }

    return 0;
}

4. 斐波那契查找

斐波那契查找利用斐波那契数列来确定查找点,适用于有序数组。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
// 生成斐波那契数列
void generateFibonacci(int fib[], int n) {
    fib[0] = 0;
    fib[1] = 1;
    for (int i = 2; i < n; i++) {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
}
// 斐波那契查找函数
int fibonacciSearch(int arr[], int size, int target) {
    int fib[100]; // 存储斐波那契数列
    generateFibonacci(fib, 100);

    int fibM = 0; // 斐波那契数列的索引

    // 找到大于等于数组长度的最小斐波那契数
    while (fib[fibM] < size) {
        fibM++;
    }

    // 创建临时数组,长度为 fib[fibM] - 1
    int* temp = (int*)malloc((fib[fibM] - 1) * sizeof(int));
    for (int i = 0; i < size; i++) {
        temp[i] = arr[i];
    }
    for (int i = size; i < fib[fibM] - 1; i++) {
        temp[i] = arr[size - 1];
    }

    int left = 0;
    int right = size - 1;

    while (left <= right) {
        int mid = left + fib[fibM - 1] - 1;

        if (temp[mid] == target) {
            free(temp);
            return (mid < size) ? mid : size - 1; // 找到目标,返回索引
        } else if (temp[mid] < target) {
            left = mid + 1;
            fibM -= 2; // 继续在右半部分查找
        } else {
            right = mid - 1;
            fibM -= 1; // 继续在左半部分查找
        }
    }

    free(temp);
    return -1; // 未找到目标
}
int main() {
    int arr[] = {10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 85;

    int result = fibonacciSearch(arr, size, target);

    if (result != -1) {
        printf("元素 %d 在索引 %d 处找到\n", target, result);
    } else {
        printf("元素 %d 未找到\n", target);
    }

    return 0;
}

算法特点总结

  • 顺序查找
  • 简单,适用于无序数组,时间复杂度为 (O(n)。

  • 二分查找

  • 效率高,适用于有序数组,时间复杂度为 O(log n))。

  • 插值查找

  • 在均匀分布的有序数组中性能优于二分查找,时间复杂度平均为 (O(log log n)),最坏为 (O(n)。

  • 斐波那契查找

    通过斐波那契数列确定查找点,避免了除法运算,适用于有序数组,时间复杂度为 (O(log n)。

相关推荐
x_xbx2 小时前
LeetCode:26. 删除有序数组中的重复项
数据结构·算法·leetcode
WitsMakeMen2 小时前
RoPE 算法原理?算法为什么只和相对位置有关
人工智能·算法·llm
WolfGang0073212 小时前
代码随想录算法训练营 Day09 | 栈与队列 part01
数据结构
0 0 02 小时前
CCF-CSP 38-4 月票发行【C++】考点:动态规划DP+矩阵快速幂
c++·算法·动态规划·矩阵快速幂
北漂Zachary2 小时前
Mysql中使用sql语句生成雪花算法Id
sql·mysql·算法
aini_lovee2 小时前
MATLAB圆锥滚子轴承滚子参数分析程序
人工智能·算法·matlab
_olone2 小时前
牛客每日一题:显生之宙(Java)
java·开发语言·算法·牛客
嫂子开门我是_我哥3 小时前
心电域泛化研究从0入门系列 | 第二篇:心电信号预处理全攻略——扫清域泛化建模的第一道障碍
人工智能·算法·ecg
wefg13 小时前
【算法】算数基本定理、分解质因数
算法