数据结构和算法之——二分查找上

二分查找(Binary Search)的思想非常简单,但看似越简单的东西往往越难掌握好,想要灵活运用就更加困难。

1. 二分查找的思想?

生活中二分查找的思想无处不在。一个最常见的就是猜数游戏,我随机写一个 0 到 99 的数,然后你来猜我写的是什么。猜的过程中,我会告诉你每次是猜大了还是猜小了,直到猜中为止。假如我写的数是 23,猜数过程如下所示。

最多只需要 7 次就猜出来了,这个过程是很快的。同理,要查找某个数据是否在给定的数组中,我们同样也可以利用这个思想。

二分查找针对的是一个有序的数据集合,查找思想有点类似于分治,每次都通过和中间元素进行比较,将待查找区间缩小为之前的一半,直到找到要查找的元素或者区间缩小为 0 为止。

2. 二分查找的时间复杂度?

我们假设数据大小为 n,每次查找数据大小都会缩小为原来的一半,最坏情况下,直到查找区间缩小为空时停止查找。

若经过 k 次区间缩小最后变为空,则 $\frac{n}{2^k} = 1, k = log_2n$,所以二分查找的时间复杂度为 $O(logn)$。

这种对数时间复杂度的算法是一种非常高效的算法,有时候甚至比时间复杂度为常量级的算法还要高效。因为常量级的时间复杂度对应的常数可能非常大,比如 O(100), O(1000),因此这些算法有时候可能还没有 $O(logn)$ 的算法执行效率高。

2. 简单二分查找的算法实现?

循环法

float Binary_Search(float data[], int left, int right, float value)
{
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (value == data[mid])
        {
            return mid;
        }
        else if (value < data[mid])
        {
            right = mid - 1;
        }
        else
        {
            left = mid + 1;
        }
    }

    return -1;
}

递归法

float Binary_Search(float data[], int left, int right, float value)
{
    if (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (value == data[mid])
        {
            return mid;
        }
        else if (value < data[mid])
        {
           return Binary_Search(data, left, mid-1, value);
        }
        else
        {
            return Binary_Search(data, mid+1, right, value);
        }
    }

    return -1;
}

注意事项

  • 循环退出条件 left <= right
  • mid = left + ((right-left) >> 1),用移位运算优化计算性能
  • left 和 right 的更新分别是 mid+1 和 mid-1

3. 二分查找的应用场景?

二分查 找依赖的是顺序表结构,也就是数组,需要能够按照下标随机访问元素

二分查找针对的是有序数据,如果数据无序,需要先进行排序。而如果有频繁的插入、删除操作,则每次查找前都需要再次排序,这时候,二分查找将不再适用。

数据量太小可以直接遍历查找,没有必要用二分查找。但如果数据之间的比较操作非常耗时,比如数据为长度超过 300 的字符串,则不管数据量大小,都推荐使用二分查找。

而如果数据量过大,则意味着我们需要用非常大的连续内存空间来存储这些数据,内存开销可能无法满足

获取更多精彩,请关注「seniusen」!

原文地址:https://www.cnblogs.com/seniusen/p/9846467.html

时间: 2024-10-11 13:12:15

数据结构和算法之——二分查找上的相关文章

【数据结构与算法】二分查找

基本思想 首先将给定的值K与表中中间位置元素比较,若相等,则查找成功:若不等,则所需查找的元素只能在中间数据以外的前半部分或者后半部分,缩小范围后继续进行同样的查找,如此反复,直到找到为止. 代码实现 /** * 源码名称:BinarySearch.java * 日期:2014-08-14 * 程序功能:二分查找 * 版权:[email protected] * 作者:A2BGeek */ public class BinarySearch { public static int binaryS

数据结构与算法之二分查找

问题:如果有一个有100个元素的已经排好序的数组,然后给你一个数,让你判断这个数组里面是否有这个数,你该怎样去做? 最简单的方法就是从数组的第一个元素开始,逐一与所给的数比较,直到比较完所有数组的元素为止,这种查找方法叫简单查找,是一个费事的方法.但我们想,既然这100个数都已经排好序了,那么我先拿中位数与所给数比较,如果两者匹配则问题解决.如果中位数比所给数大,那么所给数可能存在与中位数左边,我们就可以拿左边那些数的中位数与所给数比较:如果中位数比所给数小,那么所给数可能存在与中位数的右边,我

数据结构与算法之-二分查找

概念     二分查找又称折半查找,它是一种效率较高的查找方法.它的时间复杂度为O(logn)     二分查找要求:有序的线性表 基本思想     二分查找的基本思想是划分当前查找区间,区间的范围一步一步的缩小,如果找到直接返回,反之直到区间只有一个元素时停止 实现     设R为一个值递增的有序线性表     实现步骤: 首先确定该区间的中点位置:mid=[(low+high)/2] 然后将key值与R[mid]的值比较:若相等,则直接返回当前mid,否则进行确定新的区间操作,这分为两种情况

查找算法:二分查找、顺序查找

08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活.此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205 查找算法 查找算法是在存在的序列(list) 中查找特定的目标(target),要求序列中每个记录必须与一个关键词(key)关联才能进行查找. 查找算法通常需要两个输入: 1.被查找的序列 2.要查找的关键词 查找算法的输出参数和返回值: 1.返回类型为 Error_co

算法学习——二分查找(折半查找)

算法学习--二分查找 注意点 1. 二分查找的前提是有序的数组 2. 建议使用[start,end)的区间寻找,符合规范 3. 使用的是递归法 递归的人口 private static int find(int[] temp, int x) { //如果要查找的数x比数组的最后一个数要大,则找不到数值,返回-1 if (x > temp[temp.length - 1]) { return -1; } return find(temp, 0, temp.length, x);//进入递归 } 递

【数据结构与算法】顺序查找

基本思想 顺序查找是最简单的查找方法,从线性表的一端开始,依次将每个记录的关键字与给定值进行比较. 代码实现 /** * 源码名称:SeqSearch.java * 日期:2014-08-13 * 程序功能:顺序查找 * 版权:[email protected] * 作者:A2BGeek */ public class SeqSearch { public static int seqSearch(int[] in, int key) { int length = in.length; int

算法系列&lt;二分查找&gt;

二分查找又称折半查找,是针对有序顺序表的查找,前提:数据是顺序存储的,已经按照关键词进行升序排序.查找成功返回索引值,查找不成功返回-1. 下面用java来实现二分查找算法: /** * 二分查找:针对已排好序的序列,查找成功返回所在位置的索引值,查找不成功返回-1 * 查找的最好时间复杂度:O(1),最坏时间复杂度O(logN),平均时间复杂度:O(logN) * 测试case: * case1:{1} 查找1 * case2:{1} 查找2 * case3:{} 查找1 * case4:{1

常见算法之二分查找

1.算法思想 二分查找采用分而治之的思想.要求被查找的集合必须是有序的.主要思路: 根据起始位置和结束位置,确定中间位置. 拿目标值与中间位置的值做比较,假如目标值大于中间位置取值,则起始位置为中间位置加1. 假如目标值小于中间位置取值,则结束位置为中间位置减1. 直至起始位置小于等于结束位置,找到目标值的位置即索引. 2.代码实现 2.1.基于Python3.x实现 代码如下: 1 #coding:utf-8 2 def half_search(lst,key): 3 start = 0 4

二分算法入门——二分查找

二分查找,无论是从名字还是理论都十分简单一个算法,其博大精深,简直恐怖.Jon Bentley:90%以上的程序员无法正确无误的写出二分查找代码. 别人不知道,反正我早上是写了好久,这个查找算法,将查找的复杂度从 o( n ) 降到了 o( logn ) ,当之无愧的的好算法,更是许多高级算法的优化策略之一. 二分查找之基本思路 虽然二分查找是一个很吊的算法,但是跟很多算法一样,需要使用的基础条件——序列有序! 先假设一个单调非增序列:1 2 3 4 5 6 ,求找到3的位置,地球人都会马上这么