二分查找的学习

来自: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\n",a[m]);
38     else
39         cout<<"NO"<<endl;
40     return 0;
41 }
时间: 2024-10-10 13:04:33

二分查找的学习的相关文章

二分查找法学习

1.题目 已有一个10个元素的整形数组a,且按值从小到大有序.输入一个整数x,然后在数组中查找x,如果找到,输出相应的下标,否则,输出"Not Found". 二分查找法前提:在一个严格递增的序列中找出给定的数字X. 2.思路 初始化指针在数组的开头和结尾,然后得到中间数,进行比较,移动头尾指针,进行一半的取舍.当找到的mid>low,则最小数一定在mid的右侧,当mid<high,最小数一定在mid的左侧(或者是mid). 3.学习二分法中主要遇到的不足/难点: (1)对

【转】二分查找算法学习札记

说明作者:那谁blog: http://www.cppblog.com/converse转载请注明出处. 二分查找算法基本思想二分查找算法的前置条件是,一个已经排序好的序列(在本篇文章中为了说明问题的方便,假设这个序列是升序排列的),这样在查找所要查找的元素时,首先与序列中间的元素进行比较,如果大于这个元素,就在当前序列的后半部分继续查找,如果小于这个元素,就在当前序列的前半部分继续查找,直到找到相同的元素,或者所查找的序列范围为空为止. 用伪代码来表示, 二分查找算法大致是这个样子的: lef

【从零学习经典算法系列】分治策略实例——二分查找

1.二分查找算法简介 二分查找算法是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组 为空,则代表找不到.这种搜索算法每一次比较都使搜索范围缩小一半.折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn). 二分查找的优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且

算法学习一~分治法~二分查找,快速的找~

现在编程也算是走上门了,但是没有把算法掌握下来只能说自己还是门外汉,所以以后我们就开始努力的学习算法,现在把自己每天的学习分享在这里希望大家能喜欢,并且我也要在这里整理我一天的学习和思路,. 二分查找..大家经常需要在一个数组中寻找某个值.如果是一个已经拍好序的话那么可以很快的找到.我们考虑下暴力查找,就是a[n],中找一个m,那么最好时是o(1),最差时是0(n),最终平均情况就是长度n/2.这样的时间复杂度不算很高但是可以改进到logn的级别. 1 #include<stdio.h>//算

javascript学习6-练习之3二分查找算法

二分查找算法,对数据进行查找并且显示位置. 核心思想:将所查找数据与查询数组中间的数进行比较,findVal<midVal,则在左边进行二分查找,否则在右边进行二分查找递归调用 具体代码如下: 1 //二分查找 2 var string2=[1,3,42,88,123,143]; 3 var leftIndex=0; 4 var rightIndex=5; 5 function binarySearch(string2,findVal,leftIndex,rightIndex) 6 { 7 if

java数据结构学习(一)之二分查找

  二分查找法与我们在孩童时期玩过的猜数的游戏一样,这个游戏里一个朋友会让你猜他正想的一个1至100的数,当你猜了一个数后,他会告诉你三种选择的一个:你猜的比她想的大,或小,或猜中了.为了能用最少的次数猜中,必须从50开始猜,如果她说你猜的太小,则推出那个数在51-100之间,所以下一次猜75((51+100)/2),如果她说有些大,那你就会在51-74之间才,下一次猜(51+74)/2=62.直到猜中她所给的数. 下面给出我们猜1-100的数,key为33的过程: 只需7次就可以猜中答案.下面

在路上---学习篇(一)Python 数据结构和算法 (5)二分查找、二叉树遍历

独白: 利用算法进行查找指定元素,最近学习二分查找和二叉树遍历.二分查找前提是在有序中进行查找,二叉树引入了树的概念.树的概念其中有许多小知识点,也是一种新的数据结构.还是之前的感悟,需了解其本质才会写出更好的算法. 二分查找 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用

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

算法学习--二分查找 注意点 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);//进入递归 } 递

Java学习 (七)、数组,查找算法,二分查找法,冒泡排序,选择排序,插入排序

一.常用数组查找算法 工作原理:它又称为顺序查找,在一列给定的值中进行搜索,从一端的开始逐一检查每个元素,知道找到所需元素的过程. 例1:查找指定的数在数组中出现的位置,找到返回下标,找不到返回-1 1 import java.util.Scanner; 2 public class LinearSearch{ 3 public static void main(String []argas) 4 { 5 int [] array={10,100,90,65,80,92}; 6 System.o