基本查找/顺序查找
这个无需怎么介绍,简而言之就是,对数据进行遍历,然后找到对应的要查找数据
二分查找
前提要求:数据必须是2有序的
思路:每次就是对半查找,如下图简要的概述
举例:一组数据为7,23,79,81,103,127,131,147,现在我们要查找数据127
代码如下
package aaa;
import java.util.Scanner;
public class suan_fa {
public static void main(String[] args) {
int []arr={7,23,79,81,103,127,131,147};
Scanner sc=new Scanner(System.in);
int num= sc.nextInt();
System.out.println(find(arr,num));
}
public static int find(int []arr,int num){
int min=0;
int max=arr.length-1;
while(true){
if(min>max){
return -1;
}
int mid=(min+max)/2;
if(num>arr[mid]){
min=mid+1;
}
else if(num<arr[mid])
{
max=mid-1;
}
else {
return mid;
}
}
}
}
加上注释的代码如下图
插值查找(了解即可)
把上面二分查找的mid的计算公式替换掉就行
要求:数据分布要尽可能均匀
斐波那契查找(了解即可)
分块查找
分块查找的核心:块内无序,块外有序
如何理解?
举一个例子
如图中一串数据分成了4大块,可以看到这4大块,每一块里面的顺序是无序的,但是块2的最小值一定大于块1的最大值,所以块外是有序的
到底如何书写这个代码,我们以下面的例子为例:
一段数据为16,5,9,12,21,18,32,23,37,26,45,34,50,48,61,52,73,66
目的:查找50所在的索引
我们到底要分多少块呢?
一般情况:块数=数据个数开根号,但是这不是绝对的
如这个题目按理说要分为4板块,但是为了每个板块内的数据个数都差不多,最后选择分为3大块
16,5,9,12,21,18
32,23,37,26,45,34
50,48,61,52,73,66
代码实现如下
package aaa;
import java.util.Scanner;
public class bbb {
public static void main(String[] args) {
int []arr={16,5,9,12,21,18,
32,23,37,26,45,34,
50,48,61,52,73,66};
block b1=new block(21,0,5);
block b2=new block(45,6,11);
block b3=new block(73,12,17);
block []blockArr={b1,b2,b3};
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
System.out.println(getIndex(blockArr,arr,num));
}
public static int getIndex(block []blockArr,int []arr,int num){
int indexBlock=findIndex(blockArr,num);
if(indexBlock==-1)
return -1;
int startIndex=blockArr[indexBlock].getStart();
int endIndex=blockArr[indexBlock].getEnd();
for (int i = startIndex; i < endIndex; i++) {
if(arr[i]==num){
return i;
}
}
return -1;
}
public static int findIndex(block[]blockArr,int num){
for(int i=0;i<blockArr.length;i++){
if(num<blockArr[i].getMax()){
return i;
}
}
return -1;
}
}
class block{
private int max;
private int start;
private int end;
public block(){
};
public block(int max,int start,int end){
this.max=max;
this.start=start;
this.end=end;
}
public void setMax(int max) {
this.max = max;
}
public void setStart(int start) {
this.start = start;
}
public void setEnd(int end) {
this.end = end;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public int getMax() {
return max;
}
}
带有注释的代码如下图
分块查找的扩展:
如果给定的数据不是有规律的怎么办?如下图
只需在块类里面加上一个min的成员变量就行,这是为了确定好数据在哪个块,剩下的就和上面的一样了