【算法•日更•第一期】查找算法:简单实现二分

▎二分

『算法思想』

  二分也就是二分查找,又叫折半查找。这种算法正如其名,每一次都要分一半。废话不多说,直接抛砖引玉:

Q:现在来思考一个问题:在一千以内我已经心中想好了一个数(不耍赖),你可以随意询问我一个数,我只会说大了、小了和猜对了,想必你一定玩过,那么请问怎样询问才能使用次数最少?

  Answer:

  其实有常识的人都知道,第一次说500;第二次说(第一次大了)250或(第一次小了)750;第三次125、375、625或875……以此类推。每一次都要砍一半询问,这样无疑不需要每个数都被查找一遍。如果你这样干过,那么可以说你已经会了二分的思想了。可能我没有说清楚,那么就再举个例子吧:(我心里想着666)

A:500?

B:小了

A:750?

B:大了

A:625?

B:小了

A:687?

B:大了

A:656?

B:小了

A:671?

B:大了

A:663?

B:小了

A:667?

B:大了

A:665?

B:小了

A:666?

B:猜对了

『算法复杂度分析』

  由于每一次都会分掉一半,因此时间复杂度就是O(log n)。

  形象一些说明就是最多查找n以2为底数的对数次。

  对数在数学中,对数是对求幂的逆运算,正如除法是乘法的倒数,反之亦然。(copy自百度)比如说n=1024,log 1024=10,因为210=1024。

『算法图解』

  如果用图的形式来表示太out了,还是用自己做的flash吧,不喜勿喷

  

『算法实现』

  二分查找算法实现起来相对容易,就不加注释了,大概说一下流程:输入一串数字和被查找的数字 -> 排序(否则找出来的是错的)-> 二分查找 -> 输出是否有这个数字。

  代码如下:

 1 //二分查找 
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 int number[10000],n,x;
 6 int l,r,mid;
 7 int main()
 8 {
 9     cin>>n;
10     for(int i=1;i<=n;i++)
11     cin>>number[i];
12     sort(number+1,number+1+n);
13     cin>>x;
14     l=1;r=n;
15     while(l<=r)
16     {
17         mid=(l+r)/2;
18         if(x==number[mid])
19         {
20             cout<<"success!";
21             return 0;
22         }
23         if(x<number[mid]) r=mid-1;
24         if(x>number[mid]) l=mid+1;
25     }
26     cout<<"fail";
27     return 0;
28 }

『算法思想』

  典型的分治

  分治:分治,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。在计算机科学中,分治法就是运用分治思想的一种很重要的算法。分治法是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)等等。(copy自百度)

原文地址:https://www.cnblogs.com/TFLS-gzr/p/11132480.html