zoukankan      html  css  js  c++  java
  • 二分查找的学习

    来自:http://www.acmerblog.com/ubiquitous-binary-search-5345.html

    我们都知道二分查找算法,实际上二分查找以及其扩展应用是很广泛的。这里收集了一些和二分查找有关的有趣问题。强烈建议大家看完问题后最小化浏览器,先尝试自己去解决,然后再看代码,问题都不是太难。

    问题1描述

    给一个已经排序的数组,其中有N个互不相同的元素。要求使用最小的比较次数找出其中的一个元素。(你认为二分查找在排序数组里找一个元素是最优的算法的吗?)

    不需要太多的理论,这是一个典型的二分查找算法。先看下面的代码:

     1 // 返回要查找元素的下标,-1为没有找到
     2 int BinarySearch(int A[], int l, int r, int key)
     3 {
     4     int m;
     5     while( l <= r )
     6     {
     7         m = l + (r-l)/2;
     8 
     9         if( A[m] == key ) //第一次比较
    10             return m;
    11 
    12         if( A[m] < key ) // 第二次比较
    13             l = m + 1;
    14         else
    15             r = m - 1;
    16     }
    17 
    18     return -1;
    19 }

    理论上,我们最多需要 logN+1 次比较。仔细观察,我们在每次迭代中使用两次比较,除了最后比较成功的一次。实际应用上,比较也是代价高昂的操作,往往不是简单的数据类型的比较。减少比较的次数也是优化的方向之一。

    下面是一个比较次数更少的实现:

     1 // 循环不变式: A[l] <= key &  A[r] > key
     2 // 边界: |r - l| = 1
     3 // 输入: A[l .... r-1]
     4 int BinarySearch(int A[], int l, int r, int key)
     5 {
     6     int m;
     7     while( r - l > 1 )
     8     {
     9         m = l + (r-l)/2;
    10 
    11         if( A[m] <= key )
    12             l = m;
    13         else
    14             r = m;
    15     }
    16     if( A[l] == key )
    17         return l;
    18     else
    19         return -1;
    20 }

    在while循环中,我们仅依赖于一次比较。搜索空间( l->r )不断缩小,我们需要一个比较跟踪搜索状态。

    需要注意的,要保证我们恒等式(A[l] <= key & A[r] > key)正确,后面还会用到循环不变式。

    自己可以实现一下:

     1 #include <stdio.h>
     2 #include <math.h>
     3 #include <queue>
     4 #include <vector>
     5 #include <stack>
     6 #include <map>
     7 #include <string>
     8 #include <string.h>
     9 #include <algorithm>
    10 #include <iostream>
    11 using namespace std;
    12 int binarysearch(int a[],int l,int r,int k){
    13     int mid;
    14     while(r-l>1){
    15         mid=(r+l)/2;
    16         if(a[mid]<=k)
    17             l=mid;
    18         else
    19             r=mid;
    20     }
    21     if(a[l]==k)
    22         return l;
    23     else
    24         return -1;
    25 }
    26 int main()
    27 {
    28     int a[10];
    29     int n,m,i,j;
    30     for(int i=0;i<5;i++){
    31         cin>>a[i];
    32     }
    33     sort(a,a+5);
    34     scanf("%d",&n);
    35     m=binarysearch(a,0,5,n);
    36     if(m!=-1)
    37         printf("%d
    ",a[m]);
    38     else
    39         cout<<"NO"<<endl;
    40     return 0;
    41 }
  • 相关阅读:
    java -inally转
    11.Android-Xml读写
    10.Android-SharedPreferences使用
    9.Android-读写SD卡案例
    8.Android-简单的登录案例编写
    7.Android-压力测试、单元测试、日志猫使用
    python 向mysql中存储图片以及读取图片
    Android Studio 4.0+ 中新的 UI 层次结构调试工具
    微信小程序又放大招,代码包的大小限制由1M扩到2M
    硅谷禁书全集(5册)- 带完整封面目录,全面优化版
  • 原文地址:https://www.cnblogs.com/wangmengmeng/p/4711243.html
Copyright © 2011-2022 走看看