二分查找(分治法)。

二分查找也是一种分治法的实现,每一次查找将数据分为两个部分,问题规模都减小一半。这样查找的时间复杂度为logN。因为其实查找过程建立了一棵有N个节点的二叉树,查找次数是这棵树的高度 logN+1,所以复杂度是O(logN)。

Java实现的二分查找

查找基类

/**
* 查找基类
* @author junjun
*
*/
public class Search
{
/**
* 在数组s[p...q]上查找r
* @param s 待查数组
* @param p
* @param q
* @param r 待查的数
* @return 找到返回坐标,否则返回-1
*/
public int search(int [] s,int p,int q,int r) {return -1;};
}

二分查找类

/**
* 二分查找类
* @author junjun
*
*/
public class BinarySearch extends Search
{
/**
*  二分查找 在s[p...q]上查找r
*  @param s 待查找的数组 按照升序排列
*  @param p
*  @param q
*  @return 如果找到 返回找到元素的下标,否则返回-1
*/
public int search(int[] s, int p, int q,int r)
{
while(p <=q)
{
int middle = (p+q)/2;              //取中间的位置进行二分
if(r == s[middle]) return middle;  //如果找到返回middle
else if(r<s[middle]) q = middle-1;
else p = middle+1;
}
return -1;
}
/**
* @param args
*/
public static void main(String[] args)
{
BinarySearch bs = new BinarySearch();
int [] s = {0 ,1 ,1 ,2 ,3 ,3 ,4 ,5 ,8 ,9};
for(int i = 0; i < s.length;i++)
{
System.out.print("s["+i+"] = "+s[i]+" ");
}
System.out.println("\n3 is at the position:"+bs.search(s, 0, s.length-1, 3));
System.out.println("9 is at the position:"+bs.search(s, 0, s.length-1, 9));
System.out.println("11 is at the position:"+bs.search(s, 0, s.length-1, 11));
}
}

使用二分查找改进插入排序

插入排序算法需要与已排序的数组中从后向前一次比较比较的平均次数是O(n)的,我们可以由于是往已排序的子数组插入,所以可以使用二分法确定插入位置,比较次数减少到O(logN).下面就是二分法改进后的插入排序。虽然元素的比较次数减少到了O(logN),但是还是需要移动O(N2)次元素。

/**
* 使用二分搜索改进的插入排序
* @author buptjunjun
* @time 2013-1-22
*
*/
public class InsertSortBS extends Sort
{
/**
* 插入排序
* @param s 带排数列
* @param incOrDec 控制升序还是降序
* @return
*/
@Override
public int[] sort(int[] s,int incOrDec)
{
if(s == null || s.length <=1) return s;
for(int i = 1;i <s.length; i++)
{
int key = s[i];
//下面进行二分查找 寻找插入点
int insertPos = -1;// p就是要插入的位置
int p = 0;
int q = i-1;
int middle = p;
while(p<q)
{
middle = (p+q)/2;
if(s[middle] == key)
break;
else if(key < s[middle]) q = middle-1;
else p=middle+1;
}
//找到插入点 根据上面循环终止条件 决定插入点
//如果 是由p==q跳出来的 插入点就是p
//如果是由if(s[middle] == key) 跳出来的 插入点就是middle
insertPos = p==q?q:middle;
//将插入点后的元素依次往后移动
for(int j = i; j>insertPos ; j--)
{
s[j] = s[j-1];
}
//将元素插入插入点
s[insertPos] = key;
}
return s;
}
/**
* @param args
*/
public static void main(String[] args)
{
int [] s = {2,5,3,1,1,3,4,4,9,0};
int [] ret = new InsertSortBS().sort(s,Sort.INCREMENT);
new InsertSortBS().print(s);
}
}

2. 3.7 一个跪了的面试题

记得去年面试的时候一家公司,有这么一个题:”给定一个整数x和一个整数集合S,问S中是否能够找到两个数a,b使得a+b = x.” 现在在算法导论的第二章第23页找到了出处。开卷有益啊!

其实这就是一个二分查找的应用。

基本思路是:

遍历S中每一个的数,假设当前元素为为Si ,要找另一个数b使得Si+b = x,我们变换一下形式得到 b=x-Si .

其实问题就转化为在S中是否存在一个元素为b,先对S进行排序(可以使用合并排序时间是O(NlogN)),然后使用二分查找法,在logN的时间内就可以得到答案。

整个算法需要遍历整个集合S,总的时间复杂度为O(NlogN).

算法导论第2章(3) 二分查找 binary search相关推荐

  1. 二分查找(Binary Search)需要注意的问题,以及在数据库内核中的实现

    问题背景 今年的实习生招聘考试,我出了一道二分查找(Binary Search)的题目.题目大意如下: 给定一个升序排列的自然数数组,数组中包含重复数字,例如:[1,2,2,3,4,4,4,5,6,7 ...

  2. 八、二分查找(Binary Search)

    一.概述 二分查找(Binary Search,也称折半查找)--针对有序数据集合的查找算法 1.基本思想 类似分治思想,每次都通过跟区间的中间元素进行对比,将代查找的区间缩小为之前的一半,直到找到要 ...

  3. Leetcode中几道二分查找(Binary Search)的算法题总结

    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列.二分查找法的时间复杂度是对数级别的,O(lo ...

  4. ABAP性能优化之使用二分查找(Binary Search)选项

    READ命令使用顺序查找数据表,这会降低处理速度.取而代之,使用binary search的附加命令,可以使用二分查找算法,可以帮助加快内表查找速度. 在使用binary search之前 必须首先将 ...

  5. SAPABAP性能优化技巧—使用二分查找(Binary Search)选项

    READ命令使用顺序查找数据表,这会降低处理速度.取而代之,使用binary search的附加命令,可以使用二分查找算法,可以帮助加快内表查找速度. 在使用binary search之前必须首先将内 ...

  6. 二分查找 Binary Search

    明确循环不变量:变量的值可能在变化,但是它的含义是不变的 https://baike.baidu.com/item/循环不变量/8353186?fr=aladdin 如何写出正确的程序? 明确变量的含 ...

  7. python 二分查找_LeetCode基础算法题第120篇:二分查找算法

    技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后> 到中级难度,最后到hard难度全部完.目前我选择C语言,Python和Java作为实现语言,因 ...

  8. #2020寒假集训#二分入门(Binary Search)代码笔记

    二分查找--Binary Search 原理就类似于下图啦(网上看到哒,忽略这个代价) 二分的时间复杂度一般是 O(logN) 的,超开心了有木有٩(๑>◡<๑)۶ 最简单来说,它可以分为 ...

  9. 假设一动态集合S用一个长度为m的直接寻址表T来表示。请给出一个查找S中最大元素的过程。(算法导论第十一章11.1-1)

    假设一动态集合S用一个长度为m的直接寻址表T来表示.请给出一个查找S中最大元素的过程.你所给的过程在最坏情况下的运行时间是多少. (算法导论第十一章11.1-1) #include "Key ...

最新文章

  1. npm安装过程出现的问题及解决方式
  2. 如何学习开源系统有感(一)
  3. python从字符串解析方法名
  4. mysql工_mysql
  5. linux进程管理命令kill,Linux进程管理命令-kill | IT运维网
  6. 问题解决:QtCreator屏蔽指定警告:如C4819等
  7. BugkuCTF-Crypto题rsa
  8. PHP中数字检测is_numeric与ctype_digit的区别介绍
  9. 安徽省芜湖市谷歌卫星地图下载
  10. z反变换计算机控制,计算机控制4.Z变换.ppt
  11. 餐饮行业如何精准轻松获客,短期内使营业额倍增
  12. python有道云笔记_Python自动同步有道云笔记到Hexo
  13. 从年薪1万到年薪100万的日子
  14. python脚本批量修改图片像素大小和重命名
  15. 42岁大厂高管,给30岁-39岁人提个醒:这6个让你变强的习惯,要尽快养成
  16. av_dump_format
  17. Git使用命令(超详细)
  18. 别人给我的 Paypal 汇美元,如果我提现需要多少手续费?
  19. 计算机专业进铁路工资待遇,铁道通信信号工资一般是多少
  20. 联通TEWA 800改桥接

热门文章

  1. JavaSE(基础篇)——循环结构(for,while,do while)
  2. Web 建站技术网上资料收集
  3. 7-6 幸运彩票 (15 分)
  4. 自定义 WordPress 文章显示数量
  5. android自动化测试弹框,干货 | App 自动化测试痛点(弹框及首页启动加载完成判断处理)...
  6. 中国移动力撑国产5G手机,恐怕也难助它们击败苹果
  7. 分析vczh的东东(未完成)
  8. 论文笔记006-《Bootstrapping Entity Alignment with Knowledge Graph Embedding》
  9. javaScript的数学计算
  10. 行业追踪,2023-07-04,受特斯拉中报影响,汽车零部件放量强势拉升,不调整