# 三种基本版本：

## 1.1 二分查找原始版--查找某个数的下标（任意一个）

public int binarySearch(int[] a, int n, int key){
//n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while(low <= high) {
mid = low + ((high-low) >> 1);
if(key == a[mid]) {
return mid;
} else if(key < a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}

## 1.2 查找第一个大于等于某个数的下标

public int firstGreatOrEqual(int[] a, int n, int key){
//n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while(low <= high) {
mid = low + ((high-low) >> 1);
if(key <= a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low <= n ? low : -1;
}

1、条件为key<=a[mid]，意思是key小于等于中间值，则往左半区域查找。如在 {1,2,2,2,4,8,10}查找2，第一步，low=0, high=6, 得mid=3, key <= a[3]，往下标{1,2,2}中继续查找。

2、终止前一步为: low=high，得mid = low，此时如果key <= a[mid]，则high会改变，而low指向当前元素，即为满足要求的元素。如果key > a[mid]，则low会改变，而low指向mid下一个元素。

3、如果key大于数组最后一个元素，low最后变为n+1，即没有元素大于key，需要返回 -1。

## 1.3 查找第一个大于某个数的下标

public int firstGreat(int[] a, int n, int key){
//n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while(low <= high) {
mid = low + ((high-low) >> 1);
if(key < a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low <= n ? low : -1;
}

# 以上原型的扩展应用

## 2.1 查找数组中某个数的位置的最小下标，没有返回-1

public int firstIndex(int[] a, int n, int key){
//n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while(low <= high) {
mid = low + ((high-low) >> 1);
if(key <= a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return (low <= n) && (a[low] == key) ? low : -1;
}

## 2.2 查找数组中某个数的位置的最大下标，没有返回-1

public int lastIndex(int[] a, int n, int key){
//n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while(low <= high) {
mid = low + ((high-low) >> 1);
if(key < a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return (low - 1 >= 0 && (a[low - 1] == key))? low - 1: -1;
}

## 2.3 查找数组中小于某个数的最大下标，没有返回-1

public int firstLess(int[] a, int n, int key) {
// n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while (low <= high) {
mid = low + ((high - low) >> 1);
if (key <= a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return (low - 1 >= 0) ? low - 1 : -1;
}


## 2.4 查找数组中某个数的出现次数

	public int getCount(int[] a, int n, int key) {
// n + 1 个数
int first = firstGreatOrEqual2(a, n, key);
int last = firstGreat2(a, n, key);
return last - first;
}

public int firstGreatOrEqual2(int[] a, int n, int key) {
// n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while (low <= high) {
mid = low + ((high - low) >> 1);
if (key <= a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}

public int firstGreat2(int[] a, int n, int key) {
// n + 1 个数
int low = 0;
int high = n;
int mid = 0;
while (low <= high) {
mid = low + ((high - low) >> 1);
if (key < a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}

1、写此文章的目的是总结多种二分查找相似问题，网上的太多代码，边界条件杂乱且不容易理解。这里先总结出最基本的三种情况代码，再用三种情况的代码求解相似问题，理解复杂度降低。

2、一些问题，需要自己多总结，才能有理解深刻，才能写出最适合自己理解的代码。

• 本文已收录于以下专栏：

## 二分查找算法（递归与非递归两种方式）

• lovesummerforever
• 2014年04月27日 15:44
• 86914

## 浅谈-二分查找

• mengxiang000000
• 2016年10月07日 20:54
• 3243

## 二分查找

• sunmenggmail
• 2012年05月07日 08:34
• 38024

## 二分查找（递归与非递归）

• q3498233
• 2009年08月06日 17:04
• 44398

## 【C/C++】折半查找（二分查找）

• qq_31828515
• 2016年06月30日 17:34
• 14571

## 二分法与牛顿法

• hellotomhaha
• 2017年02月12日 18:51
• 591

## 二分查找（Binary Search）常见问题解决方法总结

• han____shuai
• 2017年07月17日 16:07
• 373

## 深入理解二分查找

• caobo1212
• 2012年08月25日 01:58
• 2146

## 二分查找法的实例分析

• clown05
• 2016年05月30日 00:56
• 1968

## C语言二分查找法（指针和数组实现）

/* * 编写一个函数，对一个已排序的整数表执行二分查找。 * 函数的输入包括各异指向表头的指针，表中的元素个数，以及待查找的数值。 * 函数的输出时一个指向满足查找要求的元素的指针，当未查找到...
• toto1297488504
• 2014年07月25日 23:20
• 1237

举报原因： 您举报文章：二分查找各种情况大总结 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)