[转]编程珠玑第五章二分搜索(折半查找)之java实现
http://blog.csdn.net/hwe_xc/article/details/51813080
二分搜索又称为折半查找,用来高效快速的解决如下问题:
我们需要确定排序后的数组x[0..n-1] 中是否包含目标元素t。 说的准确一点,就是已知
n>=0且x[0]<=x[1]<=x[2]…<=x[n-1],当n=0时数组为空,t与x中元素的数据类型相同。答案存在一个整数中,为-1则不在x数组中,否则返回具体位置0~n-1。
此问题看起来是个很小的问题,其实也不容易。据说第一篇二分搜索论文是1946年发表,但是对于完全没有错误的二分搜索程序却是在1962年才出现,用了16年的时间。可想而知,要想写出一个基本没有错误的程序不是那么简单的事儿。
下面列出此程序需要注意的地方
注意点
1. 一定要对数组进行排序
2. 如果被搜索的项不在数组中,需要返回 -1
3. 如果被搜索项多次出现,是否有特殊需求,比如需要返回第一次出现的位置
代码实现
/**
* 在排序好的数组中通过二分搜索t的位置(对于t重复出现不要求找出特定位置)
*
* @param a
* 排序好的数组
* @param t
* 被查找项
* @return
*/
public int binarySearch(int a[], int t) {
int i = 0, j = a.length - 1;
int result = -1;
while (i <= j) {
// 取得中间值
int m = (i + j) / 2;
// 被查找项大于中间值
if (t > a[m]) {
// 查找 m + 1 ~ j 区间
// 注意:一定是 m + 1开始,如果是m,有可能会陷入死循环之中
i = m + 1;
// 被查找项小于中间值
} else if (t < a[m]) {
// 查找 i ~ m - 1 区间
// 注意:一定是 m - 1结束,如果是m,有可能会陷入死循环之中
j = m - 1;
} else {
// 被查找项等于中间值, 直接返回
result = m;
break;
}
}
return result;
}
上面的代码是二分查找的一般形式,对于在t重复出现情况下没要求的话,完全够用了。如果需要返回第一次t出现的位置,我们又该如何写,请看下面代码:
public static int binarySearchFirstIndex(int a[], int t) {
int i = 0, j = a.length - 1;
int result = -1;
while (i <= j) {
// 取得中间值
int m = (i + j) / 2;
// 被查找项大于中间值
if (t > a[m]) {
// 查找 m + 1 ~ j 区间
// 注意:一定是 m + 1开始,如果是m,有可能会陷入死循环之中
i = m + 1;
// 被查找项小于中间值
} else if (t < a[m]) {
// 查找 i ~ m - 1 区间
// 注意:一定是 m - 1结束,如果是m,有可能会陷入死循环之中
j = m - 1;
} else {
// 被查找项等于中间值, 结果等于中间值
result = m;
// 附加判断中间值的左边值是否等于t
// 注意m > 0,如果不判断可能引起数组下表越界
if (m > 0 && t == a[m - 1]) {
// 继续查找
j = m - 1;
} else {
break;
}
}
}
return result;
}
可以看到,上面代码有一点小小的改进,会去判断中间值是否等于其左边的值,如果等于继续查找。对于查找最后一个位置,原理类似。
[转]编程珠玑第五章二分搜索(折半查找)之java实现的更多相关文章
- [书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers
本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解Ja ...
- 安卓权威编程指南 - 第五章学习笔记(两个Activity)
学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正. IntentActivityDemo学习笔记 ...
- 折半查找(java)(边学习边更新)
---恢复内容开始--- class ArrayTest3 { public static void main(String[] args) { //int [] arr=new int[]{54,4 ...
- 算法笔记_026:折半查找(Java)
目录 1 问题描述 2 解决方案 2.1 递归法 2.2 迭代法 1 问题描述 首先,了解一下何为折半查找?此处,借用<算法设计与分析基础>第三版上一段文字介绍: 2 解决方案 2.1 递 ...
- 【读书笔记】《编程珠玑》第一章之位向量&位图
此书的叙述模式是借由一个具体问题来引出的一系列算法,数据结构等等方面的技巧性策略.共分三篇,基础,性能,应用.每篇涵盖数章,章内案例都非常切实棘手,解说也生动有趣. 自个呢也是头一次接触编程技巧类的书 ...
- 《编程珠玑》第二章 aha算法
A题:给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数. 1.在文件中至少存在这样一个数? 2.如果有足够的内存,如何处理? 3.如果内存不足,仅可以用文件来进行 ...
- 《Python核心编程》第五章:数字
PS:[笔记+代码+图片]在GitHub上持续更新,欢迎star:https://github.com/gdouchufu/Core-Python-Programming 本章大纲 介绍Python支 ...
- 《UNIX网络编程》 -- 第五章
str_cli 和 str_echo 函数 需要先弄清楚 3.9 readn.writen 和 readline 函数 str_cli void str_cli(FILE *fp, int sockf ...
- Windows核心编程 第十五章 在应用程序中使用虚拟内存
第1 5章 在应用程序中使用虚拟内存 Wi n d o w s提供了3种进行内存管理的方法,它们是: • 虚拟内存,最适合用来管理大型对象或结构数组. • 内存映射文件,最适合用来管理大型数据流(通常 ...
随机推荐
- 【转】Linux下gcc生成和使用静态库和动态库详解
一.基本概念 1.1 什么是库 在Windows平台和Linux平台下都大量存在着库. 本质上来说,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不 ...
- [JLOI2011]飞行路线 不同的算法,不同的悲伤
题目 :BZOJ2763 洛谷P4568 [JLOI2011]飞行路线 一道最短路的题目,想想写个题解也不错(好久没写题解了_(:з」∠)_) 然后这道题中心思路是dijikstra处理最短路,所以没 ...
- Unity3D之通过C#使用Advanced CSharp Messenger
Advanced CSharp Messenger 属于C#事件的一种. 维基百科中由详细的说明http://wiki.unity3d.com/index.php?title=Advanced_CSh ...
- tomcat 嵌入式
背景 开源世界真是有意思,竟然还有这种玩法.以前一直想bs程序如何像cs程序作为安装包形式,这个就是个解决方案. 知识点 将tomcat嵌入到主程序中进行运行,而不是像以前将一个web项目copy到t ...
- 转-JavaWeb三大组件之Listener监听器
JavaWeb三大组件之Listener监听器一.概述1,它是一个接口,内容由我们来实现 2,它需要注册,例如注册在按钮上 3,监听器中的方法,会在特殊事件发生时被调用 二.JavaWeb中的监听器1 ...
- Chromium Embedded Framework (CEF)_3.2171.1979_v20170602_x86.tar.xz
CEF 为观看各个直播平台而特此修改的浏览器 可以单独提取 Flash 视频, 并可以修改视频的大小等功能 这次修改是主要针对 YY web 直播平台 对录屏的朋友有很大帮组 CEF_3.2171.1 ...
- Linux学习之CentOS(三)--初识linux的文件系统以及用户组等概念
Linux学习之CentOS(三)--初识linux的文件系统以及用户组等概念 进入到了Linux学习之CentOS第三篇了,这篇文章主要记录下对linux文件系统的初步认识,以及用户组.用户权限.文 ...
- mtu简单说明
总结:本地的mtu值==网络设备的mtu值是最优的,一般本地和网络设备的默认值都是1500(字节),没什么特殊需求,尽量不要修改 一.什么是 MTU 值 1 从字面上来说,MTU 是英文 Maxi ...
- pip的常用命令
前言 pip作为Python的御用包管理工具有着强大的功能,但是许多命令需要我们使用的时候借助搜索引擎查找(尤其是我), 于是我想将我使用到的命令整合下来,以后不用麻烦去找了,也希望能给你带来帮助.文 ...
- python-面向对象之继承
一.继承介绍 继承是一种新建类的方式,新建的类称之为子类或者派生类,被继承的类称为父类/基类/超类 python中继承的特点: 1.子类可以遗传/重用父类的属性 2.子类可以有多个父类 3.Pytho ...