[数据结构] 二分查找与变种二分查找

1.二分查找

  二分搜索(binary search),也称折半搜索(half-interval search)、对数搜索(logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

  除直接在一个数组中查找元素外,可用在插入排序中。

1.1 复杂度分析

 

  • 时间复杂度

      折半搜索每次把搜索区域减少一半,时间复杂度为O(Log n) 。(n代表集合中元素的个数)

  • 空间复杂度

       迭代:O(1)  递归:O(log n)

1.2 示例代码

// 递归版本
int binary_search(const int arr[], int start, int end, int key) {
    if (start > end)
        return -1;

    int mid = start + (end - start) / 2; //直接平均可能会溢位
    if (arr[mid] > key)
        return binary_search(arr, start, mid - 1, key);
    if (arr[mid] < key)
        return binary_search(arr, mid + 1, end, key);
    return mid;
}
// while循环
int binary_search(const int arr[], int start, int end, int key) {
    int mid;
    while (start <= end) {
        mid = start + (end - start) / 2; //直接平均可能会溢位
        if (arr[mid] < key)
            start = mid + 1;
        else if (arr[mid] > key)
            end = mid - 1;
        else
            return mid;
    }
    return -1;
}

2. 变种二分查找

2.1 改变数组

  升序数组a经过循环右移后,二分查找给定元素x的位置。

如a={1,2,3,4,5,6,7},循环移动后a={5,6,7,1,2,3,4}

2.2思路

  移动后的数组分为两部分,两部分内部都是升序排列的,中值mid必然属于这两部分之一。然后根据下标判断查找值是否属于这一部分,循环缩小mid值,直到arr[mid]等于查找值就返回。

2.3代码实现

 public static void main(String[] args){
          int arr[]={5,6,7,1,2,3,4};
          int out = VariantBinaryFind(arr,arr.length-1,1);
          System.out.println("下标为: "+ out);
      }
      /**
       * @param a  数组
       * @param len 数组长度
       * @param x 查找的元素
       * @return 返回查找值得下标,不存在返回 -1
       */
      public static int VariantBinaryFind(int arr[],int len,int x){
          int left = 0;
          int right = len;
          while(left<=right){
              int mid = left + (right -left)/2;
              if(arr[mid]==x){
                  return mid;
              }
              if(arr[mid] >= arr[left]) //mid在左边序列
                {
                    if(arr[left] > x || arr[mid] < x)
                        left = mid + 1;  //x在右边序列
                    else
                        right = mid - 1;  //x在左边序列
                }
                else //mid在右边序列
                {
                    if(arr[right] < x || arr[mid] > x)
                        right = mid - 1;  //x在左边序列
                    else
                        left = mid + 1;  //x在右边序列
                }
            }
            return -1;
      }

运行结果:

时间: 2024-10-10 08:53:12

[数据结构] 二分查找与变种二分查找的相关文章

SDUT 3376 数据结构实验之查找四:二分查找

数据结构实验之查找四:二分查找 Time Limit: 20MS Memory Limit: 65536KB Submit Statistic Problem Description 在一个给定的无重复元素的递增序列里,查找与给定关键字相同的元素,若存在则输出找到的位置,不存在输出-1. Input 一组输入数据,输入数据第一行首先输入两个正整数n ( n < = 10^6 )和m ( m < = 10^4 ),n是数组中数据元素个数,随后连续输入n个正整数,输入的数据保证数列递增.随后m行输

数据结构与算法实践 之 二分查找初识

今天起,我要对数据结构和基本的算法进行一些简单的复习,并在复习的基础上对其进行深入的挖掘.这篇文章先对二分查找进行一个简要的复习,在之后的文章中会对其进行深入的学习. 二分查找又叫折半查找,是最基本的几种查找算法之一.简单的看,二分法查找主要应用于在一个有序数列中进行元素的查找,其基本思路是,先用我们要查找的元素与这个有序数列中的中间位置的元素进行比较(在此我们姑且称这个元素为"中间位置元素"吧,至于这个元素怎么求我在后面会详细说明),如果相等,则返回这个"中间位置元素&qu

手撕二分查找及其变种,就是干!

一.初探二分查找 在面试的时候,尤其的一面,感觉让你手写二分,还真的不一定就能很快写出来,所以在此总结分享给大家 1 二分查找是什么? "查找"顾名思义是在一堆数去找出我们需要的数,但是我们又想更快的找出我们需要找的数,所以我们就尽量的减少查找比较的次数."二分"就是分成两份来减少我们查找次数. 不急不急,假设我们这里有十个数,我们来画图看看这是个什么神操作. 从上图我们知道,我们每次都和区间的中间项值进行比较,从而缩小查找区间的值. 2 时间复杂度? 这里我们假设

2. C#数据结构与算法 -- 查找算法(顺序查找,哈希查找,二分查找(折半),索引,二叉)

1. 顺序查找算法 ===================================================== 算法思想简单描述: 最突出的查找类型就是从记录集的开始处顺次遍历每条记录,直到找到所要的记录或者是 到达数据集的末尾.这就是所谓的顺序查找.顺序查找(也被称为线性查找)是非常容易实现 的.从数组的起始处开始,把每个访问到的数组元素依次和所要查找的数值进行比较.如果找 到匹配的数据项,就结束查找操作.如果遍历到数组的末尾仍没有产生匹配,那么就说明此数 值不在数组内. ==

看数据结构写代码(53) 静态查找表(线性查找,二分查找,斐波那契查找,插值查找)

查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录). 查找表分类:静态查找表和动态查找表. 静态查找表:只查找,而不进行插入,删除. 动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素. 静态表的 查找 大致 四种 算法: 线性查找,二分查找,斐波那契查找和插值查找. 其中 在线性查找之前,对表 无要求.对于 其余三种 需要 在查找之前 排序.插值查找 除了 需要 排序,还需要 均匀分布. 下面 给出代码: 线性查

【Java_Base】常用查找算法:顺序查找、二分查找

顺序查找 从第一个元素开始顺序比较查找. 二分查找 二分查找前提条件: 已排序的数组中查找 二分查找的基本思想是: 首先确定该查找区间的中间点位置: int mid = (low+upper) / 2; 然后将待查找的值与中间点位置的值比较: 若相等,则查找成功并返回此位置. 若中间点位置值大于待查值,则新的查找区间是中间点位置的左边区域. 若中间点位置值小于待查值,则新的查找区间是中间点位置的右边区域. 下一次查找是针对新的查找区间进行的. 1 public class Search{ 2 p

对分查找法(二分查找法,折半查找法)

二分查找法是针对已经排好序的序列进行查找 每次折半查找 算法时间复杂度,对于长度为N的序列,每次执行N/2,假设k次结束,最后到第一个N/2^k=0,所以k=logN 时间复杂度logN int binarysearch(const int array[], int x, int N) { int low, mid, high; low = 0, high = N - 1; while (low <= high) { mid = (low + high) / 2; if(array[mid] <

排序算法(冒泡,选择,插入,快速)查找算法(二分,快速)

四种排序算法 1.冒泡排序 思路分析:从前往后相邻的两个数一次进行比较,大的往下沉,小的网上 冒.当相邻的两个数的比较后发现他们的排序与排序要求相反,就互换. 代码实现 $arr = array (1,42,33,69,7,82,34,54,70,99); $len = count($arr); For($i=1;$i<$len;$i++){ For($j=0;$j<$len-$i;$j++){ If($arr[$j] > $arr[$j+1]){ $tmp = $arr[$j+1];

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

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