目录
基本查找:
数组不需要是否有序。但需要根据索引值,遍历数组。将数组中每个元素都与待查找值进行对比,是一种暴力查找方式。
二分查找算法:
又称折半查找。比较次数少,查找速度快,平均性能高。较基本查找相比效率要高很多。但前提是:数组有序。
原理分析:
以一个有序的升序数组为例,可以将待查找元素与数组中间位置的元素进行对比,若待查找元素小于中间位置的元素,则将待查找元素与前半部分数组中间位置的元素进行对比,依次类推,搜索区域变为1为止。若存在与待查找元素相同的元素,则返回索引值。反之,返回 -1。
public class BinarySelect {
/**
* 二分查找算法
* @param arr :待查找的有序数组
* @param selectNum :待查找的元素
* @return 元素索引值。如果元素不存在数组中,则返回-1。
*/
public static int binarySelect(int[] arr,int selectNum){
int start = 0; //数组查找范围的第一个元素位置的索引
int end = arr.length-1; //数组查找范围的最后一个元素位置的索引
while(start <= end) { //循环次数未知,使用while循环
//找到中间索引值
int middleIndex = (start+end)/2;
if(selectNum == arr[middleIndex]) {
return middleIndex;
}else if(selectNum < arr[middleIndex]) {
if(arr[0] < arr[arr.length-1]) { //判断数组是否是升序
end = middleIndex-1;
}else {
start = middleIndex+1;
}
}else {
if(arr[0] < arr[arr.length-1]) {
start = middleIndex+1;
}else {
end = middleIndex-1;
}
}
}
return -1; //元素不存在则返回-1
}
}
时间复杂度分析:
以一个包含N个元素的数组为例,二分查找算法每轮可以排除一半的元素:
1.第一轮,排除一半元素后剩下 N/2;
2.第二轮,继续排除一半元素后剩下 N/(2^2);
3.第三轮,继续排除一半元素后剩下 N/(2^3);
......
4.直到第m轮,继续排除一半元素后剩下 N/(2^m)=1 为止;
此时 m = log(N),即时间复杂度为 log(N) --------------------------- 以2为底
空间复杂度分析:
因为在数组元素位置交换时,需要两个临时变量存储数组前后的索引值。因此选择排序算法的空间复杂度为 O(1)