常用查找算法
- 顺序(线性)查找
- 二分查找
- 插值查找
线性查找
不要求数列有序,遍历数列,找到就返回即可
二分查找
要求序列有序
package com.atguigu.search;
import java.util.ArrayList;
import java.util.List;
public class Search {
public static void main(String[] args) {
int[] arr = {1, 8, 10, 89, 1000, 1000, 1000, 1234};
List<Integer> integers = binarySearch(arr, 0, arr.length - 1, 1234);
System.out.println(integers);
}
/**
* 二分查找
* @param arr
* @param left
* @param right
* @param value
* @return
*/
public static List<Integer> binarySearch(int[] arr, int left, int right, int value) {
if (left > right) {
return new ArrayList<>();
}
int mid = (left + right) / 2;
if (arr[mid] < value) {
//向右递归
return binarySearch(arr, ++mid, right, value);
} else if (arr[mid] > value) {
return binarySearch(arr, left, --mid, value);
}else {
List result = new ArrayList<Integer>();
result.add(mid);
int temp1 = mid - 1;
while (temp1 > 0 && arr[temp1] == value) {
result.add(temp1);
temp1--;
}
int temp2 = mid + 1;
while (temp2 < arr.length && arr[temp2] == value) {
result.add(temp2);
temp2++;
}
return result;
}
}
}
插值查找
- 对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快
- 关键字分布不均匀的情况下,该方法不一定比二分法好
package com.atguigu.search;
import java.util.ArrayList;
import java.util.List;
public class Search {
public static void main(String[] args) {
int[] arr = {1, 8, 10, 89, 1000, 1000, 1000, 1234};
List<Integer> indexs = insertValueSearch(arr, 0, arr.length - 1, 1000);
System.out.println(indexs);
}
/**
* 插值查找法
* @param arr
* @param left
* @param right
* @param value
* @return
*/
public static List<Integer> insertValueSearch(int[] arr, int left, int right, int value) {
//校验参数合法性
if (left > right || value < arr[0] || value > arr[arr.length - 1]) {
return new ArrayList<>();
}
//计算mid
int mid = left + (right - left) * (value - arr[left]) / (arr[right] - arr[left]);
int midValue = arr[mid];
if (midValue < value) {
return insertValueSearch(arr, ++mid, right, value);
} else if (midValue > value) {
return insertValueSearch(arr, left, --mid, value);
} else {
ArrayList<Integer> result = new ArrayList<>();
result.add(mid);
int temp = mid - 1;
while (temp > 0 && arr[temp] == value) {
result.add(temp);
temp--;
}
temp = mid + 1;
while (temp < arr.length && arr[temp] == value) {
result.add(temp);
temp++;
}
return result;
}
}
}