说到查找数组的中的某个元素,首先需要再次声明的是,数组访问的时间复杂度是O(1),而查找元素的时间复杂度是O(n)
二分搜索是数组查找元素中的一个小的考点,一起来看一下吧
二分搜索的原理非常简单,前提条件是数组有序,有序的数组我们在查找元素的时候再一个一个去比较就显得有些多余了,所以利用有序的特性,我们每次都和中间的元素进行比较,如果比中间的元素小,那么就把范围缩短到左半边,如果比中间的元素大,那么就把范围缩短到右半边,这是一种分治的思想,可以大大提升查找效率。
通过一个例子来看一下吧
有9个排好序的数组如图所示:
假如现在我们要查找元素78,那么首先把这9个数字的中间取出来,即(0+8)/2=4,那么首先和56,进行比较,发现78比56大,那么就把范围缩短成右边的子数组
现在在这个序列中,再次取出中间的数字 (5+8)/2=6,6号元素是78,那么就匹配上,返回6号元素。
一起来看一下代码实现吧:
递归实现:
/**
* 递归实现二分搜索
* @param arr 数组
* @param num 查找元素
* @return 返回查找元素在数组中的位置
*/
private static int binarySearchRecursion(int[] arr, int num) {
return binarySearch(arr,num,0,arr.length-1);
}
private static int binarySearch(int[] arr, int num, int low, int high) {
if(low <= high) {
int mid = (low+high)/2;
if(arr[mid] == num) {
return mid;
} else if(arr[mid] > num) {
return binarySearch(arr,num,low,mid-1);
} else {
return binarySearch(arr,num,mid+1,high);
}
}
return -1;
}
非递归实现:
/**
* 非递归实现二分搜索
* @param arr 数组
* @param num 查找元素
* @return 返回查找元素在数组中的位置
*/
private static int binarySearchNonRecursion(int[] arr,int num) {
//自己定义两个指针
int low = 0,high = arr.length-1;
int mid = -1;
while(low <= high) {
mid = (low+high)/2;
if(arr[mid] == num) {
return mid;
} else if(arr[mid] < num) {
low = mid + 1;
} else if(arr[mid] > num) {
high = mid - 1;
}
}
return -1;
}