Algoritmo de búsqueda
Análisis e implementación de búsqueda lineal
Hay una secuencia numérica: {1, 9, -1, 34, 89, 11}, para determinar si el nombre está incluido en la secuencia [Búsqueda secuencial] requiere que si se encuentra, solicitará encontrarlo y dar el valor de subíndice.
public class SeqSearch {
public static void main(String[] args) {
int arr[] = {
1, 9, -1, 34, 89, 11};//无序数组
int z = seqSearch(arr, 89);
if (z == -1){
System.out.println("没有找到");
}else {
System.out.println("找到值,下标为" + z);
}
int arz[] = {
9,34,11};
int[] ints = seqzSearch(arr, arz);
for (int i = 0; i < ints.length; i++) {
System.out.print("下标为" +"[" + ints[i] + "]");
}
}
/**
* 这里我们实现的线性查找是找到一个满足条件的值,就返回
* @param arr
* @param value
* @return
*/
public static int seqSearch(int[] arr, int value) {
//线性查找是逐一比对,发现有相同的值时,就返回下标
for (int i = 0; i < arr.length; i++) {
if (arr[i] == value){
return i;
}
}
return -1;
}
public static int[] seqzSearch(int[] arr,int[] arz){
int seqz[] = new int[arz.length];
int index = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arz.length; j++) {
if (arr[i] == arz[j]){
seqz[index] = i;
index++;
}
}
}
return seqz;
}
}
Análisis y realización de búsquedas binarias
Realice una búsqueda binaria en una matriz ordenada {1,8, 10, 89, 1000, 1234}, ingrese un número para ver si este número existe en la matriz y busque el subíndice; de lo contrario, aparecerá el mensaje "no existe tal número". .
Análisis de la idea de búsqueda binaria:
Primero determine el subíndice en el medio de la matriz mid = (left + right) / 2
Luego compare
findVal con arr [mid] para encontrar el número que desea encontrar 2.1 findVal> arr [mid], significa que el número que desea encontrar está en el lado derecho de mid, por lo que necesita buscar a la derecha de forma recursiva.
2.2 findVal <arr [mid], significa que el número que desea encontrar está a la izquierda de mid, por lo que debe buscarlo de forma recursiva a la izquierda.
2.3 findVal == arr [mid] Si lo encuentra, regrese.
¿Cuándo debemos finalizar la recursividad?
- Finalice la recursividad cuando se encuentre.
- Toda la matriz es recursiva, pero findVal aún no se encuentra, y la recursividad debe finalizar cuando left> right.
Código
//注意:使用二分查找的前提是 该数组是有序的。
public class BinarySearch {
public static void main(String[] args) {
int arr[] = {
1, 8, 10, 88, 1000, 1234};
int resIndex = binarySearch(arr, 0, arr.length, 88);
System.out.println("resIndex=" + resIndex);
}
//二分查找算法
/**
*
* @param arr 数组
* @param left 查找时左边的索引
* @param right 右边的索引
* @param findVal 要查找的值
* @return 如果找到就返回下标, 如果没有找到, 就返回-1
*/
public static int binarySearch(int[] arr, int left, int right, int findVal) {
//当left > right 时,说明递归整个数组,但是没有找到
if (left > right){
return -1;
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (findVal > midVal) {
//向 右递归
return binarySearch(arr, mid + 1, right, findVal);
} else if (findVal < midVal) {
//向 左递归
return binarySearch(arr, left, mid - 1, findVal);
}else {
return mid;
}
}
}
Optimización de algoritmos
//注意:使用二分查找的前提是 该数组是有序的。
public class BinarySearch {
public static void main(String[] args) {
int arr[] = {
1, 8, 10, 88, 1000, 1000, 1000, 1000, 1234,1234,6666,6666};
List<Integer> list = binarySearchz(arr, 0,arr.length - 1, 6666);
System.out.println(list);
}
//二分查找算法
/**
*
* @param arr 数组
* @param left 查找时左边的索引
* @param right 右边的索引
* @param findVal 要查找的值
* @return 如果找到就返回下标, 如果没有找到, 就返回-1
*/
public static int binarySearch(int[] arr, int left, int right, int findVal) {
//当left > right 时,说明递归整个数组,但是没有找到
if (left > right){
return -1;
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (findVal > midVal) {
//向 右递归
return binarySearch(arr, mid + 1, right, findVal);
} else if (findVal < midVal) {
//向 左递归
return binarySearch(arr, left, mid - 1, findVal);
} else {
return mid;
}
}
//思考题
/*
题:{1,8,10,89,1000,1000,1234}当一个有序数组中,有多个相同的数值时
如何将所有的数值都查找到,比如这里的1000
思路分析:
1.在找到mid 索引值时,不要马上返回
2.向mid 索引值得左边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
3.向mid 索引值的右边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
4.将ArrayList返回
*/
public static List<Integer> binarySearchz(int[] arr, int left, int right, int findVal) {
//当left > right 时,说明递归整个数组,但是没有找到
if (left > right){
return new ArrayList<Integer>();
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (findVal > midVal) {
//向 右递归
return binarySearchz(arr, mid + 1, right, findVal);
} else if (findVal < midVal) {
//向 左递归
return binarySearchz(arr, left, mid - 1, findVal);
} else {
/*思路分析:
1.在找到mid 索引值时,不要马上返回
2.向mid 索引值得左边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
3.向mid 索引值的右边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
4.将ArrayList返回*/
List<Integer> resIndexlist = new ArrayList<Integer>();
//2.向mid 索引值得左边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
int temp = mid - 1;
while (true){
if (temp < 0 || arr[temp] != findVal){
//退出
break;
}
//否则,就把temp 放入到集合resIndexlist中
resIndexlist.add(temp);
temp -= 1;//temp左移
}
resIndexlist.add(mid);
//3.向mid 索引值的右边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
temp = mid + 1;
while (true){
if (temp > arr.length -1 || arr[temp] != findVal){
//退出
break;
}
//否则,就把temp 放入到集合resIndexlist中
resIndexlist.add(temp);
temp += 1;//temp左移
}
// resIndexlist.add(mid);//别忘了把之前找到的放进去
return resIndexlist;
}
}
}
Análisis e implementación de búsqueda por interpolación
Principio de búsqueda de interpolación
El algoritmo de búsqueda de interpolación es similar a la búsqueda binaria, la diferencia es que la búsqueda de interpolación comienza desde el medio adaptativo cada vez.
La fórmula para encontrar el índice medio en la mitad de la búsqueda, bajo representa el índice izquierdo a la izquierda, alto representa el índice derecho a la derecha. La clave
es el valor de búsqueda del que hablamos anteriormente.
int mid = low + (alto - bajo) * (clave - arr [bajo]) / (arr [alto] -
arr [bajo]); / 插值 索引 /
Correspondiente a la fórmula del código anterior:
int mid = left + (derecha - izquierda) * (findVal - arr [izquierda]) / (arr [derecha]
- arr [izquierda])
Ilustre el algoritmo de búsqueda de interpolación 1-100
Ideas específicas:
Array arr = [1, 2, 3,…, 100]
Si necesitamos encontrar el valor 1
Usando la búsqueda binaria, necesitamos recurrir varias veces para encontrar 1
Utilice el algoritmo de búsqueda de interpolación: int mid = left + (right - left) * (findVal - arr [left]) / (arr [right] - arr [left])
int mid = 0 + (99 - 0) * (1 - 1) / (100 - 1) = 0 + 99 * 0/99 = 0
Por ejemplo, el valor que buscamos es 100
int mid = 0 + (99 - 0) * (100 - 1) / (100 - 1) = 0 + 99 * 99/99 = 0
- 99 = 99
En resumen, algoritmo de búsqueda de interpolación -> conjunto de cálculos de fórmulas