查找

根据数据结构的不同,查找可以分为线性表查找,树表查找和哈希表查找等。

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;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值