一、线性查找算法【easy】
package search;
public class SeqSearch
{
public static void main(String[] args)
{
int[] arr = {1, 3, 9, 8, 7, -1, 2}; //没有顺序的数组
int index = seqSearch(arr, 7);
if(index == -1)
System.out.println("没有找到值 " + 7);
else
System.out.println("值为 " + 7 + "的下标为 " + index);
}
/**
* 这里我们实现的线性查找是找到一个满足条件的值,就返回
* @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;
}
}
二、二分查找算法
2.1思路
2.2代码实现
package search;
public class BinarySearch
{
//注意:使用二分查找的前提是该数组是有序的
public static void main(String[] args)
{
int[] arr = {1, 8, 10, 89, 1000, 1024, 2048};
int findVal = 1024;
int resIndex = binarySearch(arr, findVal, 0, arr.length - 1);
if(resIndex == -1)
{
System.out.println("数组中未找到值 : " + findVal);
}
else
System.out.println("resIndex: " + resIndex);
}
/**
* 二分查找算法
* @param arr 数组
* @param findVal 要查找的值
* @param l 左边的索引
* @param r 右边的索引
* @return 如果找到就返回下标,如果没有找到,就返回-1
*/
public static int binarySearch(int[] arr, int findVal, int l, int r)
{
if(l > r)
return -1;
int mid = (l + r) / 2;
if(findVal > arr[mid])
return binarySearch(arr, findVal, mid + 1, r);
else
if(findVal < arr[mid])
return binarySearch(arr, findVal, l, mid - 1);
else
return mid;
}
}
2.3二分查找算法功能完善
当一个有序数组中,有多个相同的数值时,如何将所有的数值都查到。
如:[1, 9 , 88, 582, 1000, 1000, 1000, 99999]
思路:
1、在找到mid索引值,不要马上返回
2、向mid索引值的左边扫描,将所有满足1000的元素的下标,加入到集合ArrayList
3、 向mid索引值的右边扫描,将所有满足1000的元素的下标,加入到集合ArrayList
4、将ArrayList返回
package search;
import java.util.ArrayList;
import java.util.List;
public class BinarySearch
{
//注意:使用二分查找的前提是该数组是有序的
public static void main(String[] args)
{
int[] arr = {1, 8, 10, 89, 1000, 1000, 1000, 1024, 2048};
int findVal = 1000;
List<Integer> resIndex = binarySearch2(arr, findVal, 0, arr.length - 1);
if(resIndex == null)
{
System.out.println("数组中未找到值 : " + findVal);
}
else
System.out.println("resIndex: " + resIndex);
}
public static List<Integer> binarySearch2(int[] arr, int findVal, int l, int r)
{
if(l > r)
return new ArrayList<Integer>();
int mid = (l + r) / 2;
if(findVal > arr[mid])
return binarySearch2(arr, findVal, mid + 1, r);
else
if(findVal < arr[mid])
return binarySearch2(arr, findVal, l, mid - 1);
else
{
/**
* 1、在找到mid索引值,不要马上返回
* 2、向mid索引值的左边扫描,将所有满足1000的元素的下标,加入到集合ArrayList
* 3、 向mid索引值的右边扫描,将所有满足1000的元素的下标,加入到集合ArrayList
* 4、将ArrayList返回
*/
List<Integer> resIndexlist = new ArrayList<Integer>();
//向mid索引的左边扫描,将所有满足1000的元素的下标,加入到集合ArrayList中
int temp = mid - 1;
while(true)
{
if(temp < 0 || arr[temp] != findVal)
{
break;
}
//否则,将temp放入到resIndexlist
resIndexlist.add(temp);
temp = temp - 1; //左移
}
resIndexlist.add(mid);
//向mid索引的右边扫描,将所有满足1000的元素的下标,加入到集合ArrayList中
temp = mid + 1;
while(true)
{
if(temp > arr.length-1 || arr[temp] != findVal)
{
break;
}
//否则,将temp放入到resIndexlist
resIndexlist.add(temp);
temp = temp + 1; //左移
}
return resIndexlist;
}
}
}
三、插值查找算法
3.1工作原理
3.2代码实现
package search;
import java.util.Arrays;
public class InsertValueSearch
{
public static void main(String[] args)
{
int[] arr = new int[100];
for(int i = 0; i < 100; i++)
{
arr[i] = i + 1;
}
System.out.println(Arrays.toString(arr));
int index = insertValueSearch(arr, 0, arr.length - 1, 1);
System.out.println("index: " + index);
}
//编写插值算法
//插值查找算法,也是要求数组是有序的
/**
*
* @param arr
* @param left
* @param right
* @param findVal
* @return 如果找到,就返回相应的下标,如果没有找到,返回 -1
*/
public static int insertValueSearch(int[] arr, int left, int right, int findVal)
{
//注意:findVal < arr[0] 和 findVal > arr[arr.length - 1]必须有,否则得到的mid可能越界
if(left > right || findVal < arr[0] || findVal > arr[arr.length - 1])
{
return -1;
}
//求出mid
int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);
int midVal = arr[mid];
if(findVal > midVal) //向右递归
{
return insertValueSearch(arr, mid + 1, right, findVal);
}
else if(findVal < midVal) //向左递归
{
return insertValueSearch(arr, left, mid - 1, findVal);
}
else //找到
{
return mid;
}
}
}
四、斐波那契数列