博客
关于我
七大查找算法
阅读量:87 次
发布时间:2019-02-26

本文共 3530 字,大约阅读时间需要 11 分钟。

查找算法概述

查找定义

在计算机应用中,查找是常用的基本运算。查找的目标是,在给定的数据集合中找到一个关键字与给定值相等的数据元素或记录。查找算法根据数据集合的结构和操作特点,采取不同的策略来提高效率。


查找算法分类

查找算法可以从多个维度进行分类:

  • 静态查找与动态查找

    静态查找表指查找表中没有插入或删除操作的表,动态查找表则允许插入和删除操作。

  • 无序查找与有序查找

    无序查找适用于存储结构无序的数据集合,而有序查找则要求数据集合必须是有序的。


  • 平均查找长度(ASL)

    平均查找长度是指在查找成功的情况下,系统平均需要进行的比较次数。其计算公式为:

    [ ASL = \frac{1}{n} \sum_{i=1}^{n} C_i ]
    其中,( C_i ) 是找到第 ( i ) 个数据元素时已经进行的比较次数,( n ) 是数据集合的总数。


    常见查找算法

    1. 顺序查找

    基本思想:从数据结构的一端开始,逐个比较元素的关键字,直到找到目标元素或遍历结束。

    优点:简单易实现,适用于存储结构为顺序存储或链接存储的线性表。

    缺点:时间复杂度较高,为 ( O(n) )。

    C++ 实现示例

    int SequenceSearch(int a[], int value, int n) {
    int i;
    for (i = 0; i < n; i++) {
    if (a[i] == value) {
    return i;
    }
    }
    return -1;
    }

    2. 二分查找

    基本思想:基于有序数据集合,利用中间点的比较,递归或迭代缩小查找范围。

    优点:时间复杂度优于顺序查找,期望时间复杂度为 ( O(\log_2 n) )。

    缺点:需要维护有序性,插入或删除操作会影响效率。

    C++ 实现示例

    int BinarySearch1(int a[], int value, int n) {
    int low = 0, high = n - 1;
    while (low <= high) {
    int mid = low + (high - low) / 2;
    if (a[mid] == value) {
    return mid;
    } else if (a[mid] > value) {
    high = mid - 1;
    } else {
    low = mid + 1;
    }
    }
    return -1;
    }

    3. 插值查找

    基本思想:根据二分查找的基础,通过计算目标值在数据集合中的比例位置,确定下一步查找点。

    优点:在目标值分布较为均匀的情况下,平均性能优于二分查找。

    缺点:当数据分布不均匀时,性能可能不佳。

    C++ 实现示例

    int InsertionSearch(int a[], int value, int low, int high) {
    int mid = low + (value - a[low]) / (a[high] - a[low]) * (high - low);
    if (a[mid] == value) {
    return mid;
    } else if (a[mid] > value) {
    return InsertionSearch(a, value, low, mid - 1);
    } else {
    return InsertionSearch(a, value, mid + 1, high);
    }
    }

    4. 斐波那契查找

    基本思想:利用斐波那契数列的黄金比例特性,确定下一步查找点。

    优点:在静态有序数据集合中,平均性能优于二分查找。

    缺点:实现较为复杂。

    C++ 实现示例

    int FibonacciSearch(int a[], int value, int low, int high, int k) {
    if (low > high) {
    return -1;
    }
    int mid = low + F[k-1] - 1;
    if (value < a[mid]) {
    k--;
    return FibonacciSearch(a, value, low, mid - 1, k);
    } else if (value > a[mid]) {
    return FibonacciSearch(a, value, mid + 1, high, k);
    } else {
    return mid;
    }
    }

    5. 树表查找

    5.1 二叉查找树

    基本思想:通过二叉树的结构,快速定位目标值。

    优点:插入和查找的时间复杂度均为 ( O(\log n) )。

    缺点:最坏情况下可能退化为 ( O(n) )。

    C++ 实现示例

    struct Node {
    int key;
    Node* left;
    Node* right;
    };

    6. 平衡查找树

    6.1 2-3查找树

    基本思想:通过节点分支的多样性,提高查找效率。

    优点:保证树的平衡性,避免最坏情况下高时间复杂度。

    C++ 实现示例

    struct Node {
    int key;
    Node* left;
    Node* right;
    };

    7. 哈希查找

    基本思想:通过哈希函数将键映射到数组索引,实现快速查找。

    优点:平均时间复杂度为 ( O(1) )。

    缺点:可能产生冲突,需要处理冲突。

    C++ 实现示例

    #include 
    using namespace std;
    int main() {
    unordered_map
    hashTable;
    hashTable[5] = 10;
    cout << hashTable[5] << endl; // 输出 10
    return 0;
    }

    B 树和 B+ 树

    基本思想:允许一个节点包含多个键,用于高效存储和查找大块数据。

    优点:适合文件系统和数据库,减少磁盘IO次数。

    C++ 实现示例

    #include 
    #include
    int main() {
    BTree bt;
    bt.insert(5, "A");
    bt.insert(10, "B");
    cout << bt.search(5) << endl; // 输出 "A"
    return 0;
    }

    分块查找

    基本思想:将数据按块存储,通过索引表定位块,再在块内进行查找。

    优点:提高查找效率,适合大数据量和小块的情况。

    C++ 实现示例

    #include 
    #include
    int main() {
    vector
    data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int blockSize = 4;
    vector
    indexTable;
    for (int i = 0; i < data.size(); i += blockSize) {
    indexTable.push_back(data[i - 1]);
    }
    int target = 5;
    int block = upper_bound(indexTable, target) - 1;
    int pos = block * blockSize + (target - indexTable[block]);
    cout << "查找结果为:" << data[pos] << endl;
    return 0;
    }

    总结

    查找算法的选择取决于具体需求:从简单的顺序查找到高效的哈希查找,以及平衡树和分块查找等,都有各自的应用场景。理解和比较这些算法,有助于在实际项目中做出更优的选择。

    转载地址:http://mwtk.baihongyu.com/

    你可能感兴趣的文章
    nginx负载均衡器处理session共享的几种方法(转)
    查看>>
    nginx负载均衡的5种策略(转载)
    查看>>
    nginx负载均衡的五种算法
    查看>>
    nginx转发端口时与导致websocket不生效
    查看>>
    Nginx运维与实战(二)-Https配置
    查看>>
    Nginx配置Https证书
    查看>>
    Nginx配置ssl实现https
    查看>>
    Nginx配置TCP代理指南
    查看>>
    Nginx配置——不记录指定文件类型日志
    查看>>
    nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
    查看>>
    Nginx配置代理解决本地html进行ajax请求接口跨域问题
    查看>>
    nginx配置全解
    查看>>
    Nginx配置参数中文说明
    查看>>
    nginx配置域名和ip同时访问、开放多端口
    查看>>
    Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
    查看>>
    Nginx配置如何一键生成
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
    查看>>