一、基本查找 / 顺序查找
核心:从0索引开始挨个往后查找
private static boolean basicSearch(int[] arr, int number) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == number) {
return true;
}
}
return false;
}
二、二分查找 / 折半查找
前提:数组中的数据必须是有序的
核心:每次排除一半的查找范围
优势:提高查找效率
- min和max表示当前要查找的范围
- mid是在min和max中间的
- 如果要查找的元素在mid的左边,缩小范围时,min不变,max等于mid减1
- 如果要查找的元素在mid的右边,缩小范围时,max不变,min等于mid加1
private static int search(int[] arr, int number) {
// 记录查找的最小值和最大值
int min = 0;
int max = arr.length - 1;
while (true) {
// 判断最小值大于最大值,不存在
if (min > max) {
return -1;
}
// 找到中间位置
int mid = (min + max) / 2 ;
// 拿中间位置的值和number比较
if (arr[mid] > number) {
// number在mid的左边,最小值min不变,最大值max=mid-1
max = mid - 1;
} else if (arr[mid] < number) {
// number在mid的右边,最大值max不变,最小值min=mid+1
min = mid + 1;
} else {
// 相等,找到数据,返回下标
return mid;
}
}
}
三、插值查找
前提:有序序列,并且元素呈现均匀分布
public static int interpolation_search(int[] arr, int begin, int end, int ele) {
// 如果[begin,end] 不存在,返回 -1
if (begin > end) {
return -1;
}
//如果搜索区域内只有一个元素,判断其是否为目标元素
if (begin == end) {
if (ele == arr[begin]) {
return begin;
}
//如果该元素非目标元素,则查找失败
return -1;
}
// 找到中间元素所在的位置
int mid = begin + ((ele - arr[begin]) / (arr[end] - arr[begin]) * (end - begin));
// 递归的出口
if (ele == arr[mid]) {
return mid;
}
// 比较 ele 和 arr[mid] 的值,缩小 ele 可能存在的区域
if (ele < arr[mid]) {
// 新的搜索区域为 [begin,mid-1]
return interpolation_search(arr, begin, mid - 1, ele);
} else {
// 新的搜索区域为 [mid+1,end]
return interpolation_search(arr, mid + 1, end, ele);
}
}
四、斐波那契查找
五、分块查找
分块原则1:前一块中的最大数据,小于后一块中所有的数据(块内无序,块间有序)
分块原则2:块数一般是长度开根号
核心思路: 先确定查找的元素在哪一块,然后在块内挨个查找
public class BlockSearch {
public static void main(String[] args) {
//定义原始数组,并分块
int[] arr = {16,4,19,12,21,18,32,23,37,26,45,34,50,48,61,62,73,76};
//创建三个块对象
Block b1 = new Block(21,0,5);
Block b2 = new Block(45,6,11);
Block b3 = new Block(76,12,17);
//创建索引表
Block[] blockArr = {b1,b2,b3};
//定义要查找的元素
int number = 26;
//调用方法求Index
int Index = getIndex(blockArr,arr,number);
System.out.println(Index);
}
//查询number的索引值
private static int getIndex(Block[] blockArr, int[] arr, int number) {
int Indexblock = -1;
for (int i = 0; i < blockArr.length; i++) {
if(number <= blockArr[i].getMax()){
Indexblock = i;
break;
}
}
int startIndex = blockArr[Indexblock].getStartIndex();
int endIndex = blockArr[Indexblock].getEndIndex();
for (int i = startIndex; i <= endIndex; i++) {
if(arr[i] == number){
return i;
}
}
return -1;
}
}