在 算法系列(一)基本概念 一文中,简单介绍了算法基本概念,算法复杂度评估,常用算法证明方式。这篇文章介绍一下查找算法,主要是二分查找算法。
从n个元素中A0,A1....An-1中,找到要找到的元素x,最简单的方法是遍历n个元素,找到元素x则返回x的位置,这种算法的时间复杂度为O(n)。
如果这n个元素是有序的,我们不需要从头到尾遍历一遍就可以找到要查找的元素,可以使用二分法。二分查找的时间复杂度是O(lgn)
二分查找的前提是元素有序(一般是升序),基本思想是拿中间元素A[m]与要查找的元素x进行比较,如果相等,则已经找到,如果A[m]比x大,那么要找的元素一定在A[m]前边,如果A[m]比x小,那么要找的元素一定在A[m]后边。没进行一次查找,数组规模减半。反复将子数组规模减半,直到发现要查找的元素,或者当前子数组为空。
例如,在[1,2,3,4,5]中查找2
第一次找到的数字下标是(0+4)/2=2,找到的数字是3,3<2,要找的数字位置位于[0,2)之间
第二次找到的数字下标是(0+1)/2=0,找到的数字是1,1<2,要找的数字位于(0,1]之间
第三次找到的数字下标是(1+1)/2=1,找到数字2,返回找到的位置1.
如果这个时候找到的数字不是1,那么说明数组中没有要找的数字。
需要注意的点就是区间位置,既然A[m]不等于x,下一次肯定不是从m这个位置开始找的,而是以m+1作为下一个起始位置,或者m-1作为下一个开始位置
二分查找有两种实现方式,一种是递归实现,一种是非递归实现
直接上代码
package com.algorithm.tree;
import java.util.Arrays;
/**
* 二分查找
*
* @author chao
*
*/
public class BinarySearchTree {
/**
* 非递归二分查找
*
* @param num
* @param number
* @return
*/
public static int binarySearch(int num[], int number) {
if (num == null || num.length == 0) {
return -1;
}
int start, end, mid;
start = 0;
end = num.length - 1;
while (start <= end) {
mid = (start + end) / 2;
if (num[mid] == number)
return mid;
else if (num[mid] > number) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
/**
* 递归查找
*
* @param num
* @param number
* @return
*/
public static int RecursivebinarySearch(int num[], int start, int end, int key) {
int mid = (start + end) / 2;
if (num == null || num.length == 0 || key < num[start] || key > num[end]) {
return -1;
} else if (num[mid] > key) {
return RecursivebinarySearch(num, start, mid - 1, key);
} else if (num[mid] < key) {
return RecursivebinarySearch(num, mid + 1, end, key);
} else {
return mid;
}
}
public static void main(String[] args) {
int num[] = { 3, 5, 7, 9, 10 };
Arrays.sort(num);
System.out.println(binarySearch(num, 7));
System.out.println(binarySearch(num, 8));
System.out.println(RecursivebinarySearch(num, 0, num.length - 1, 7));
System.out.println(RecursivebinarySearch(num, 0, num.length - 1, 8));
}
}
这里的排序直接使用了java的api,后边再详细介绍排序算法
算法实现代码github地址为https://github.com/robertjc/simplealgorithm
后续会不断补充,有些地方写的可能有问题,请多指教。
欢迎扫描二维码,关注我的公众账号