查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算。
顺序查找
基本思想:表的一端开始顺序扫描线性表,依次将扫描到的值和给定值相比较。
public boolean orderQuery(int[]values,int value){
for(int i=0;i<values.length;i++){
if(values[i]==value){
return true;
}
}
return false;
}
二分查找
基本思想:每次和中间的数相比较,然后确定在左边一半查找还是右边一半查找,每次下来都减少一半的数量。
public boolean twoQuery(int[]values,int value){
int start=0;
int end=values.length-1;
int minddle=0; //中间位置下标
while(true){
minddle=(end+start)/2; //每次对折一下
//确定需要查找的值在左边还是右边
if(value<values[minddle]){
end=minddle-1;
}else if(value>values[minddle]){
start=minddle+1;
}
if(value==values[minddle]){
return true;
}
if(start>end){
return false; //当开始下标超过结束下标即表示该值没有
}
}
}
块查找
基本思想:将数组平均分为N块但是要满足N-1块里面最大值比N块最小值小,分块完成后建立索引数组 索引数组里面放置每块的最大值。
查找先去索引数组查找对应的块再查找。
/**
* 基于二分的查找块(可替换为顺序查找)
* @param index 索引数组
* @param value 需要判断的值
* @return 返回该值对应的块索引
*/
public int getBlock(int[]index,int value){
int start=0,end=index.length-1,minddle=0;
while(true){
if(start>end){
break;
}
minddle=(end+start)/2;
if(value<index[minddle]){
end=minddle-1;
}else if(value>index[minddle]){
start=minddle+1;
}else{
//恰好为块的最大值
return minddle;
}
}
//是否在索引之内
if(start>=index.length||end<0){
return -1;
}else {
//块的位置
return start;
}
}
/**
*
* @param values 目标数组
* @param index 索引数组(里面放置的是每块的最大值)
* @param value 需要查找的值
* @return 是否包含
* 模仿参数:int[]values={12,22,24, 25,30,31, 35,52,52, 59}
* int[]index={24,31,52,59};
*/
public boolean contain(int[] values,int[]index,int value){
//根据索引计算出具体块的下标
int blockIndex=getBlock(index,value);
if(blockIndex==-1){
return false;
}
int size=0;
//每块的个数
if(values.length%index.length==0){
size=values.length/index.length;
}else{
size=values.length/index.length+1;
}
int start=blockIndex*size; //所在块开始下标
int end=0; //所在块结束下标
if(blockIndex==index.length-1){//当为最后一块时,需要注意最后一块的结束下标,并不可能最后一块也是size个
end=values.length-1;
}else{
end=(blockIndex+1)*size-1;
}
//顺序查找(可替换为二分查找)
for(int i=start;i<=end;i++){
if(values[i]==value){
return true;
}
}
return false;
}