根据数据结构的不同,查找可以分为线性表查找,树表查找和哈希表查找等。
1,线性表查找:
(1)顺序查找:当线性表是无序表时,只能用顺序查找。较为简单,不做赘述。
(2)二分查找:要求线性表是有序表,现假定该有序表是以升序排列的。其基本思想是:维护三个变量low,middle,high,初始时,low = 0; high = n-1;middle = (low+high)/2;如果data[middle]等于目标值,则查找结束;如果data[middle]大于目标值,说明目标值在data[middle]左侧,使high = middle-1,middle = (low+high)/2;如果data[middle]小于目标值,说明目标值在data[middle]的右侧,使low = middle+1;重复以上步骤,直至low>high,查找完毕。算法实现:
public class Main{
public static void main(String[] args){
int[] a = {2,3,4,6,6,13,53};
System.out.print(new Main().binSearch(a,3));
}
int binSearch(int[] data, int key){
int low = 0;
int high = data.length-1;
int middle;
while(low<=high){
middle = (low+high)/2;
if(data[middle]==key) return middle;//返回关键字所在下标
if(data[middle]<key){
low = middle+1;
}else{
high = middle-1;
}
}
return -1;//未找到,则返回-1
}
}
(3)分块查找,将线性表分成多块,维护一张索引表,记录每块的最大值和块的起始下标、结尾下标,索引表的记录按照每块的最大值来有序排列。建立了索引表之后,将关键字先与索引表中的每块最大值进行比较,确定关键字在哪块中。然后在该块中进行顺序查找。算法实现:
public class Main{
public static void main(String[] args){
int[] a = {2,3,4,6,6,13,53};
System.out.print(new Main().blockSearch(a,3));
}
int blockSearch(int[] data, int key){
BlockInfo[] blocks = getBlockArray(data);
int blockIndex = -1;
for(int i=0; i<blocks.length; i++){
if(key>blocks[i].maxValue&&key<blocks[i+1].maxValue){
blockIndex = i+1;
break;
}
}
if(blockIndex!=-1){
for(int i=blocks[blockIndex].begin; i<=blocks[blockIndex].end; i++){
if(data[i]==key) return i;
}
}
return -1;
}
//内部类,定义索引表节点的属性
class BlockInfo{
int begin;
int end;
int maxValue;
}
//分块
public BlockInfo[] getBlockArray(int[] data){
int le = data.length;
int blockLe = (int)Math.sqrt(le);
int blockNu = le/blockLe;
BlockInfo[] blocks = new BlockInfo[blockNu];
for(int i=0; i<blockNu; i++){
BlockInfo block = new BlockInfo();
block.begin = blockLe*i;
if(block.begin+blockLe>le) block.end = le-1;
else block.end = block.begin+blockLe-1;
int maxValue = data[block.begin];
for(int j=block.begin+1; j<=block.end; j++){
if(data[j]>maxValue) maxValue = data[j];
}
block.maxValue = maxValue;
blocks[i] = block;
}
//用插入排序法对生成的blocks数组进行排序
for(int i=1; i<blockNu; i++){
if(blocks[i].maxValue<blocks[i-1].maxValue){
BlockInfo tmp = blocks[i];
int j = 0;
for(j=i-1; j>=0&&blocks[j].maxValue>tmp.maxValue; j--){
blocks[j+1] = blocks[j];
}
blocks[++j] = tmp;
}
}
return blocks;
}
}