• 二分查找



    题目描述

    给定已排好序的 (n) 个元素 (a[0 : n - 1]) ,在这 (n) 个元素中找出某一特定元素 (x)

    说明

    • 输入
      • 第一行输入数组元素个数 (n)
      • 第二行输入数组各个元素 ({a[0] ... a[n - 1]})
      • 第三行输入所要找的元素 (x)
    • 输出
      • 输出元素 (x) 在数组中的下标,如果不存在则输出 (-1)

    示例

    输入: 
    5
    1 3 5 7 9
    3
        
    输出: 
    1
    
    输入:
    6
    1 5 6 10 12 20
    9
    
    输出:
    -1
    

    题解

    首先可以采用顺序查找方法,逐个查找 ({a[0 : n - 1]}) 中的元素,直至找出元素 (x) 或者搜索完整个数组。在最坏情况下,这样做的时间复杂度显然是 (O(N))

    顺序查找没有利用数组元素有序的性质。二分查找采用分治策略,将 (n) 个元素分成个数大致相同的两部分,取 (a[n / 2])(x) 比较。如果 (x) 等于 (a[n / 2]) ,则找到 (x) ,算法结束。如果 (x) 小于 (a[n / 2]) ,则在数组 (a) 的左半部分继续按照此算法继续搜索 (x) ;如果 (x) 大于 (a[n / 2]) ,则在数组 (a) 的右半部分继续按照此算法继续搜索 (x) 。在最坏情况下,二分查找的时间复杂度是 ({O(logN)})

    当然,也可以构建哈希表来处理此问题,它的时间复杂度只是 ({O(1)}) 级别。


    代码

    #include <iostream>
    
    using namespace std;
    
    // 迭代版本
    int iterate_binary_search(int *a, int &n, const int &x);
    
    // 递归版本
    int recursion_binary_search(int *a, int &n, const int &x);
    int recursion_auxiliary(int *a, int &left, int &right, const int &x);
    
    const int size = 100;
    
    int main()
    {
        int n = 0, i = 0, a[size], x = 0;
        cin >> n;
        for (i = 0; i < n; i++)
        {
            cin >> a[i];
        }
        cin >> x;
        cout << iterate_binary_search(a, n, x) << endl;
        cout << recursion_binary_search(a, n, x) << endl;
        return 0;
    }
    
    int iterate_binary_search(int *a, int &n, const int &x)
    {
        int index = -1;
        int left = 0, right = n - 1, middle = 0;
        while (left <= right)
        {
            middle = (left + right) / 2;
            if (x == a[middle])
            {
                index = middle;
                break;
            }
            if (x > a[middle])
            {
                left = middle + 1;
            }
            else
            {
                right = middle - 1;
            }
        }
        return index;
    }
    
    int recursion_binary_search(int *a, int &n, const int &x)
    {
        int left = 0, right = n  - 1;
        return recursion_auxiliary(a, left, right, x);
    }
    int recursion_auxiliary(int *a, int &left, int &right, const int &x)
    {
        if (left > right)
        {
            return -1;
        }
        int middle = (left + right) / 2;
        if (x == a[middle])
        {
            return middle;
        }
        if (x > a[middle])
        {
            left = middle + 1;
        }
        else
        {
            right = middle - 1;
        }
        return recursion_auxiliary(a, left, right, x);
    }
    

    返回顶部

  • 相关阅读:
    一次线上遇到磁盘IO瓶颈的问题处理
    修改mysql错误日志级别
    binlog_format日志错误
    mysql重启遇到的问题
    Mysql两张表的关联字段不一致
    多线程中的join总结笔记
    java后端实习生面试题目
    javascript 中的 innerHTML 是什么意思
    为什么java实体类需要重写toString方法
    关于maven中的快照版本(snapshot)与正式版本(release)解析。
  • 原文地址:https://www.cnblogs.com/peabits/p/10913938.html
Copyright © 2020-2023  润新知