头歌学习-Java数组之一维数值数组之查找Key值

任务描述

本关任务:使用折半方法查找数组中某元素的索引,并统计出查找次数。

相关知识
顺序查找

顺序查找就是从数组的第一个元素开始,依次比较,直到找到目标数据或查找失败。

顺序查找举例:查找数组中是否存在值 432。

 
  1. public class FindTest {
  2. public static void main(String[] args) {
  3. int i;
  4. int[] arr={1,2,4,5,54,321,867,432,3};
  5. for( i=0;i<arr.length;i++){ // 顺序遍历数组中的值
  6. // 判断是否存在元素432
  7. if(arr[i]==432){
  8. System.out.print("目标值的索引为:"+i);
  9. break;
  10. }
  11. if(i==arr.length-1){
  12. System.out.println("数组中没有对应的值");
  13. }
  14. }
  15. }
  16. }

输出结果:

 
  1. 目标值的索引为:7
折半查找

能使用折半查找的前提是数组中的数据是有序的。

折半查找的原理: 假设查找的数组区间为 [min,max],min 代表起始索引,max 代表结束索引,T 代表需要查找的值。

  • 第一步:确定该区间的中间位置 K;

  • 第二步:将查找的值 T 与 array[k] 比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续折半查找;

  • 第三步:若 array[k]>T,由数组的有序性可知 array[k,k+1,……,max] 中的每个值都大于 T,故新的区间为 array[min,……,K-1],若 array[k]<T,同理可得新的查找区间为 array[k+1,……,max]。

每一次查找与中间值比较,可以确定是否查找成功,不成功的话下一次查找区间将缩小一半。

折半查找举例:查找数组中是否存在等于 80 的元素。

 
  1. public static void main(String[] args) {
  2. int [] arr={5,13,19,21,37,56,64,75,80,88,92}; // 数组必须是有序的
  3. // 定义三个变量分别记录最大、最小、中间的查找范围索引值
  4. int max=arr.length-1;
  5. int min=0;
  6. int mid;
  7. int target=21;
  8. mid=(max+min)/2;
  9. while(true) {
  10. if(target<arr[mid]) { // 如果目标元素小于中点元素
  11. max = mid-1; // max向mid前移动
  12. }
  13. else if(target>arr[mid]) { // 如果目标元素大于中点元素
  14. min = mid+1; // min向mid后移动
  15. }
  16. else {
  17. System.out.println(mid); // 找到目标元素
  18. break;
  19. }
  20. if(max<min) { // 没有找到的情况
  21. System.out.println("没有找到");
  22. break;
  23. }
  24. mid=(max+min)/2; // 重新计算中间索引值
  25. }
  26. }

执行结果:

 
  1. 3
顺序查找和折半查找

在查找速度方面,顺序查找自然是不及折半查找,我们代码中数组的长度比较小,没有太大差距,当数据量较大时,我们就能明显感觉到运行时间差距了。

从另一方面来说,顺序查找对数据要求不高,无需数据按照某种方式排列,也无需指定存储格式,顺序存储可以,链式存储也可以。所以从应用范围来说,顺序查找算法自然会更好。

编程要求

仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,使用折半方法查找数组中某元素的索引,并统计出查找次数,具体要求如下:

  • 接收给定的数据(如:4 88 43 43 98 #...,其中第一个数代表数组长度,第二个数代表需要查找的元素,其余数代表数组元素,# 号用于终止接收数据),遇到 # 号终止接收;
  • 创建数组,使用折半方法查找数组中某元素的索引,并统计出查找次数。

注意:数字分隔符为空格。

测试说明

平台将使用测试集运行你编写的程序代码,若全部的运行结果正确,则通关。

可在右侧 “测试结果”区查看具体的测试集详情。 例: 测试输入:

 
  1. 6 78 4 34 78 458 488 788 #

预期输出:

 
  1. 索引值:2。查找次数:1。

测试输入:

 
  1. 6 786 4 34 78 458 488 788 #

预期输出:

 
  1. 没有找到
    
    import java.util.Scanner;
    
    public class FindTest {
        public static void main(String[] args) {
    		
            
            Scanner sc = new Scanner(System.in);
        
            int[] arr = new int[(sc.nextInt())];    //用户控制数组长度
     
            int n = sc.nextInt();                   //需要查找的数值
    
            for (int i = 0; i < arr.length; i++){   //数组赋值
                 arr[i] = sc.nextInt();
            }
    
    //******************折半查找******************************************
           
            int min=0;
            int mid;
            int count=0;
    
            // 查找给定元素索引,并输出查找次数
            int max=arr.length-1;   //数组索引值
            mid=(max+min)/2;        //数组索引二分
    
            while(true){
                count++;
                if (n < arr[mid]){
                    max = mid - 1;
                   
                }else if(n > arr[mid]){
                    min = mid + 1;
                   
                }else{
           
                    System.out.println("索引值:" + mid + "。查找次数:" + count +"。");
                    break;
                }
    
                if(max < min){
                    System.out.println("没有找到");
                        break;
                }
    
                mid = (max + min) / 2;
            }
            
        }
    }
    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值