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

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

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)。

相关推荐
OOJO1 小时前
c++---list介绍
c语言·开发语言·数据结构·c++·算法·list
别或许3 小时前
1、高数----函数极限与连续(知识总结)
算法
田梓燊3 小时前
code 560
数据结构·算法·哈希算法
笨笨饿3 小时前
29_Z变换在工程中的实际意义
c语言·开发语言·人工智能·单片机·mcu·算法·机器人
kobesdu3 小时前
综合强度信息的激光雷达去拖尾算法解析和源码实现
算法·机器人·ros·slam·激光雷达
weixin_413063214 小时前
记录 MeshFlow-Online-Video-Stabilization 在线稳像
算法·meshflow·实时防抖
会编程的土豆4 小时前
【数据结构与算法】动态规划
数据结构·c++·算法·leetcode·代理模式
炘爚4 小时前
深入解析printf缓冲区与fork进程复制机制
linux·运维·算法
迈巴赫车主5 小时前
蓝桥杯19724食堂
java·数据结构·算法·职场和发展·蓝桥杯
6Hzlia5 小时前
【Hot 100 刷题计划】 LeetCode 78. 子集 | C++ 回溯算法题解
c++·算法·leetcode