顺序查找:
根据对应的元素在其遍历数组中比较,找到则返回
时间复杂度:O(n)
public class seqSearch {
public static void main(String[] args) {
int[] arr = {4,1,8,2,6};
int number = 2;
int index = seqSearch(arr,number);
System.out.println(index);
}
public static int seqSearch(int[] arr, int value) {
// 线性查找是逐一比对,发现有相同值,就返回下标
for (int i = 0; i < arr.length; i++) {
if(arr[i] == value) {
return i;
}
}
return -1;
}
}
二分查找:
有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功
时间复杂度:O()
public class binarySearch {
public static void main(String[] args) {
int[] arr = {1,2,4,6,8};
int low = 0;
int high = arr.length-1;
int key = 6;
int result = recursionBinarySearch(arr,key,low,high);
System.out.println(result);
}
public static int recursionBinarySearch(int[] arr,int key,int low,int high){
if(key < arr[low] || key > arr[high] || low > high){
return -1;
}
int middle = (low + high) / 2; //初始中间位置
if(arr[middle] > key){
//比关键字大则关键字在左区域
return recursionBinarySearch(arr, key, low, middle - 1);
}else if(arr[middle] < key){
//比关键字小则关键字在右区域
return recursionBinarySearch(arr, key, middle + 1, high);
}else {
return middle;
}
}
}
插值查找:基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。
时间复杂度:O(log2(log2n))
斐波那契查找:
斐波那契查找原理与前两种相似,仅仅改变了中间结点(mid)的位置,mid不再是中间或插值得到,而是位于黄金分割点附近,即mid=low+F(k-1)-1(F代表斐波那契数列)
时间复杂度:O(2n)
import java.util.Arrays;
public class FibonacciSearch {
public static int maxSize=20;
public static void main(String[] args) {
// TODO 自动生成的方法存根
//定义初始数组
int[] arr= {1,8,10,89,1000,1234};
int findVal=10;
System.out.println(fabnacciSearch(arr, findVal));
}
//构建斐波那契数列
public static int[] Fabonacci() {
int[] f=new int[maxSize];
f[0]=1;
f[1]=1;
for(int i=2;i<maxSize;i++) {
f[i]=f[i-1]+f[i-2];
}
return f;
}
//编写斐波那契查找算法
public static int fabnacciSearch(int[] arr,int findVal) {
int low=0;
int high=arr.length-1;
int k=0; //表示斐波那契分割数值得下标
int mid=0;
int[] f=Fabonacci();
//获取斐波那契分割数值的下标
while(high>f[k]-1) {
k++;
}
//因为f[k]值可能大于数组arr的长度,因此需要使用Arrays类,构造一个新的数组,并指向arr[]
//不足的部分会使用0填充
int[] temp= Arrays.copyOf(arr, f[k]);
//实际上需求使用a数组最后的数填充temp
for(int i=high+1;i<temp.length;i++) {
temp[i]=arr[high];
}
//使用while来循环处理,找到数
while(low<=high) {
mid=low+f[k-1]-1;
if(findVal>temp[mid]) { //向右查找
low=mid+1;
k-=2; //f[k]=f[k-1]+f[k-2] mid左边是f[k-1],右边是f[k-2]
}else if(findVal<temp[mid]) { //向左查找
high=mid-1;
k--;
}else {
if(high>mid) { //因为之前的temp数组填充了arr[high]
return mid;
}else {
return high;
}
}
}
return -1;
}
}