常见的查找算法汇总(含详细代码)1

电子说

1.3w人已加入

描述

温馨提示:全文14632字,因为文章长度问题 需要分五篇读完 详细文章可以进我主页!

今天就把常见****查找算法也总结个通透, 还有详细的代码解释, 真的是写完这篇感觉脑子已经不是自己的了,还希望大家好好利用。

查找算法,顾名思义就是在一堆数据中查找到你想要的那个数据。 以下就介绍几种常用的查找算法,帮助大家更好的了解其原理和使用场景。

代码

1、线性查找

1.1、基本概念及适用场景

线性查找(Linear Search),也叫顺序查找,是一种简单的查找算法,适用于无序数组或链表中的元素查找。线性查找的原理是按顺序依次扫描待查找的元素,直到找到目标元素或扫描完所有元素。

具体实现时,从数组的第一个元素开始逐个比较,如果找到目标元素,则返回其下标,否则返回未找到的标记(如-1)。如果数组中存在多个目标元素,则只会找到第一个。

线性查找的时间复杂度为O(n),其中n是待查找元素的个数,最坏情况下需要扫描整个数组或链表。

线性查找适用于以下情况:

  • 待查找的数据规模较小,或数据无序,或需要查询的数据在数组或链表的末尾。
  • 数据存储在单向链表中,没有下标的概念。

需要注意的是,线性查找的效率比较低,不适用于大规模的数据查询。

1.2、代码示例

#include 


int linearSearch(int arr[], int n, int x) {
    int i;
    for (i = 0; i < n; i++) {
        if (arr[i] == x) {
            return i;   // 找到了,返回元素下标
        }
    }
    return -1;  // 没找到,返回-1
}


int main() {
    int arr[] = {10, 20, 30, 40, 50, 60};
    int n = sizeof(arr) / sizeof(arr[0]);
    int x = 40;
    int result = linearSearch(arr, n, x);
    if (result == -1) {
        printf("元素 %d 不存在\\n", x);
    } else {
        printf("元素 %d 的下标是 %d\\n", x, result);
    }
    return 0;
}

在上述示例中,linearSearch()函数用于进行线性查找,参数 arr 表示要查找的数组,n 表示数组的长度,x 表示要查找的元素值。函数通过遍历数组中的每个元素,找到目标元素就返回其下标,若未找到则返回 -1。在 main() 函数中,声明数组并调用 linearSearch() 函数进行查找,最终输出查找结果。

2、二分查找

2.1、基本原理及注意事项

二分查找(Binary Search),也称折半查找,是一种常见的查找算法。它的 基本原理是在有序数组中查找目标元素,通过将目标元素与有序数组的中间元素进行比较,可以排除一半的元素,从而提高查找效率

二分查找适用于有序数组中的查找,可以用于查找具有单调性质的数据集合。其时间复杂度为 O(log n),相对于线性查找的 O(n),效率更高。但是,二分查找的前提是必须有序,如果需要频繁的插入和删除操作,那么维护有序性就需要额外的操作,会降低效率。

在使用二分查找时需要注意以下几点:

  1. 数组必须有序。
  2. 二分查找只适用于静态查找,即目标数组不经常变化。
  3. 目标元素必须是可比较的,可以使用小于或大于操作符进行比较。
  4. 二分查找的效率高于线性查找,但在小数据量的查找中,可能没有线性查找快。

二分查找的应用场景包括查找有序数组中的特定元素、查找第一个大于或小于给定值的元素等。

需要注意的是,虽然二分查找是一种高效的查找算法,但是在实际开发中,有时候使用哈希表等其他数据结构也能达到更高的效率,所以需要根据具体的问题场景选择合适的算法。

2.2、代码示例

当在一个有序数组查找某个元素时,二分查找是一个很高效的算法。

#include 


int binarySearch(int arr[], int l, int r, int x) {
    if (r >= l) {
        int mid = l + (r - l) / 2;


        if (arr[mid] == x) {
            return mid;
        }
        if (arr[mid] > x) {
            return binarySearch(arr, l, mid - 1, x);
        }
        return binarySearch(arr, mid + 1, r, x);
    }
    return -1;
}


int main() {
    int arr[] = {1, 3, 5, 7, 9, 11, 13};
    int n = sizeof(arr) / sizeof(arr[0]);
    int x = 7;
    int result = binarySearch(arr, 0, n - 1, x);
    if (result == -1) {
        printf("元素不在数组中");
    } else {
        printf("元素在数组中的索引为:%d", result);
    }
    return 0;
}

该代码实现了一个名为binarySearch的函数,该函数用于在一个有序数组中查找给定的元素。binarySearch函数的参数为待查找数组arr,数组左边界l,数组右边界r以及要查找的元素x

在函数内部,首先通过计算中间元素的下标来将待查找区间分为两部分。如果中间元素等于要查找的元素,则直接返回中间元素的下标。如果中间元素大于要查找的元素,则在左半部分进行递归查找。否则,在右半部分进行递归查找。

main函数中,先定义了一个有序数组arr,以及要查找的元素x。然后,调用binarySearch函数查找给定元素,并将返回值保存在变量result中。如果result的值为-1,则说明要查找的元素不在数组中;否则,输出要查找的元素在数组中的索引。

需要注意的是,二分查找算法要求待查找的数组必须是有序的。因此,在使用二分查找算法前,需要保证待查找的数组已经排好序。

3、插值查找

3.1、基本概念

插值查找是一种基于二分查找算法的优化,它的基本原理与二分查找类似,只不过插值查找根据查找键值与查找范围内值的分布情况,通过插值来确定下一步查找的位置。与二分查找相比,它可以提供更快的查找速度,尤其是数据比较分散的情况下,比如数据集中在数组的前面或后面。

插值查找的具体实现步骤如下:

  1. 确定查找范围,初始化起始位置left为0,结束位置right为n-1,其中n为数组长度。
  2. 计算中间位置mid,mid的值为 (key - arr[left]) / (arr[right] - arr[left]) * (right - left) + left,其中key为查找关键字,arr为待查找的有序数组。
  3. 如果arr[mid]等于key,则返回mid。
  4. 如果arr[mid]小于key,则在[mid+1, right]范围内查找。
  5. 如果arr[mid]大于key,则在[left, mid-1]范围内查找。
  6. 重复2-5步,直到查找到目标值或查找范围为空,查找失败。

需要注意的是,插值查找要求待查找的数组是有序的,否则无法保证查找结果的正确性。 此外,当数据分布较为均匀时,插值查找可以快速定位到目标值,但当数据分布不均时,可能会导致查找效率的降低。

3.2、代码示例

#include 


// 插值查找函数,array为待查找数组,n为数组长度,target为目标值
int interpolationSearch(int array[], int n, int target) {
    int low = 0, high = n - 1;
    while (low <= high && target >= array[low] && target <= array[high]) {
        int pos = low + ((double)(target - array[low]) / (array[high] - array[low])) * (high - low);
        if (array[pos] == target) {
            return pos;
        } else if (array[pos] < target) {
            low = pos + 1;
        } else {
            high = pos - 1;
        }
    }
    return -1;
}


// 测试
int main() {
    int array[] = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
    int n = sizeof(array) / sizeof(int);
    int target = 12;
    int index = interpolationSearch(array, n, target);
    if (index != -1) {
        printf("目标值%d在数组中的位置是%d\\n", target, index);
    } else {
        printf("目标值%d在数组中不存在\\n", target);
    }
    return 0;
}

在上面的代码中,interpolationSearch() 函数采用了插值查找算法的实现,其中 array 为待查找数组,n 表示数组长度,target 表示目标值。在查找过程中,我们首先计算出目标值所在的估计位置 pos,然后根据 array[pos] 的值与目标值 target 的大小进行比较,并更新查找的范围,直到找到目标值或者确定目标值不存在于数组中。最终,该函数返回目标值在数组中的位置,如果不存在则返回 -1。

main() 函数中,我们定义了一个数组 array 和目标值 target,并调用 interpolationSearch() 函数进行查找,将结果输出到控制台。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分