Java数据结构(八)—— 查找算法
查找算法
常用的查找算法:
-
顺序(线性)查找
-
二分查找/折半查找
-
插值查找
-
斐波那契查找
线性查找
-
一个数列可有序,可无序
代码实现
/**
* 线性查找
* 这里是找到一个即返回
* @param arr 查找的数据数列
* @param val 需要查找的值
* @return
*/
public static int seqSearch(int[] arr,int val){
//线性查找是逐一比对,发现相同值,返回下标
for (int i = 0; i < arr.length; i++) {
if (arr[i] == val){
return i;
}
}
return -1;
}
二分查找(Binary Search)
-
有序数列才可使用二分查找
思路分析
-
首先确定该数组的中间下标mid = (left + right)/ 2
-
然后让需要查找的数findVal和arr【mid】比较
-
findVal > arr[mid],向右查询
-
findVal < arr[mid],向右查询
-
findVal == arr[mid],找到,返回
-
-
结束递归的条件
-
找到就结束
-
递归完整个数组,未找到,结束递归,left > right
-
基本写法
public static int binarySearch(int[] arr,int left,int right,int findVal){
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;
}
}
新需求
当一个数组中有多个相同的数值是 ,将所有数值都查到
代码实现
package com.why.search;
import com.sun.jdi.PathSearchingVirtualMachine;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;
/**
* @Description TODO 当一个数组中有多个相同的数值是 ,将所有数值都查到,使用二分查找
* @Author why
* @Date 2020/11/1 16:35
* Version 1.0
**/
public class NewBinarySearch {
public static void main(String[] args) {
int[] arr = {1,8,8,10,10,10,10,11};
List res = newBinarySearch(arr, 0, arr.length - 1, 8);
if (!res.isEmpty()){
System.out.println(res);
}else {
System.out.println("未找到");
}
}
/**
* 二分查找查找多条数据
*
* 思路:
* 找到mid值时,不要马上返回
* 向mid 索引值的左边扫描将所有满足查找值的元素下标加入到集合
* 向右扫描将所有满足查找值的元素下标加入到集合
* @param arr
* @param left
* @param right
* @param findVal
* @return
*/
public static List<Integer> newBinarySearch(int[] arr, int left, int right, int findVal){
if (left > right){
return new ArrayList<Integer>();
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (findVal > midVal){
return newBinarySearch(arr,mid + 1,right,findVal);
}else if (findVal < midVal){
return newBinarySearch(arr,left,mid - 1,findVal);
}else {
List<Integer> resIndexList = new ArrayList<>();
//向左边扫描
int temp = mid - 1;
while (true){
if (temp < 0