对于二分查找,是对一个已经完成排序的数组(或其他存储数据的容器)进行的对一个指定元素的查找,并返回其索引的算法。若存在查找的元素,返回指定元素的索引。若不存在直接返回-1,停止检索。
此处笔者先进行对该算法实现的分析,通俗易懂,注意跟上笔者思路。(注:笔者这里使用java语言实现)
编程重点在于理解编程思想,其实无论用什么语言写都是一样的,不过是换了一种表现形式。
来吧,上我们的思路分析:
1.把所有不可能的条件过滤
2.遍历数组,定义一个头元素指针(索引)变量,一个中间元素指针,一个尾指针元素(此处如果读者学过C/C++ 可以就理解为定义的是记录元素位置的索引)
补充:先判断查找的元素是否为首尾中间元素
3.比较查找索引位置元素和中间的指针元素和头指针或尾指针元素的大小
4.大于中间元素:将原中间指针重新赋值为头指针,中间指针在尾指针和原中间指针之间开始重新计算,尾指针保持不变
5.小于中间元素:与上面操作类似
6.循环 3 - 5 的操作, 若中间, 头 , 尾指针发生重合还没找到,表示查无此元素
7.查找结束,返回指定索引
以下,是笔者实现功能的代码:
/**
* 二分查找
* @param arr 传入查找的目标(注意:原数组必须已经排好序)
* @param ele 传入查找的指定元素
* @return 返回指定的索引
*/
public static int binnarySearch(int[] arr, int ele) {
if (arr == null) {
System.out.println("该数组不存在");
return -1;
}
int prePointer = 0;// 定义首元素指针
int midPointer = (arr.length - 1) / 2;// 此处不管元素个数是奇数还是偶数个
int tailPointer = arr.length - 1;// 定义尾元素指针
// 开始查询
for (int i = 0; i < arr.length; i++) {
// 先判断查找的元素是否为首尾中间元素
if (ele == arr[prePointer]) {
return prePointer;
}
if (ele == arr[midPointer]) {
return midPointer;
}
if (ele == arr[tailPointer]) {
return tailPointer;
}
//大于中间元素的情况
if (ele > arr[midPointer]) {
prePointer = midPointer;
midPointer = (tailPointer + prePointer) / 2; // 无论是奇数个还是偶数个
}
// 小于中间元素的情况
if (ele < arr[midPointer]) {
tailPointer = midPointer;
midPointer = (tailPointer + prePointer) / 2; // 无论是奇数个还是偶数个
}
}
// 整个循环找完,还未找到,直接返回-1
return -1;
}
以上是利用for循环实现的一种形式二分搜索。下面,笔者再利用while循环来实现二分搜索,笔者认为这里使用while循环来实现是一种更优雅的方式。
以下是while循环实现的代码:
public static int binnarySearch(int[] src , int ele) {
// 定义三个位置的指针
int prePointer = 0;
int midPointer = src.length / 2;
int tailPointer = src.length - 1;
// 此处当头指针、尾指针和中间指针的位置重合时,结束查找(这里是我们循环控制条件)
while (prePointer < tailPointer && prePointer != midPointer && tailPointer != midPointer) {
// 判断是否一开始查找的元素就位于我们的这三个指针位置
if (ele == src[prePointer]) {
return prePointer;
} else if (ele == src[midPointer]) {
return midPointer;
} else if (ele == src[tailPointer]) {
return tailPointer;
}
if (ele > src[midPointer]) {
// 更新头指针和中间指针位置
prePointer = midPointer;
midPointer = (prePointer + tailPointer) / 2;
}
if (ele < src[midPointer]) {
// 更新中间指针和尾指针位置
tailPointer = midPointer;
midPointer = (prePointer + tailPointer) / 2;
}
}
return -1;
}
写到这里,笔者已经完成了二分算法实现的一种自己的理解,如有不当之处,欢迎各位读者指出。
笔者水平有限,读者若有更好实现方法,欢迎读者分享留言在评论区,大家一起交流学习。
感谢读者阅读到这里,希望我的文章对您有一定的帮助。