Java数据结构-折半查找(二分查找)

查找要求:

1.必须采用顺序存储结构。

2.必须按关键字大小有序排列。


查找思想:

首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;
否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字
,则进一步查找前一子表,否则进一步查找后一子表。
   重复以上过程,直到找到满足条件的记录,使查找成功,
   或直到子表不存在为止,此时查找不成功。

代码1-非递归查找:

public static int Search(int arr[], int key) {
        int low = 0, high = arr.length - 1;//low high为下标
        int mid;
        while (low <= high) {
            mid = (low + high) / 2;
            if (key > arr[mid]) {
                low = mid + 1;
            } else if (key < arr[mid]) {
                high = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

代码2-递归查找:


  /**
     * @param arr 数组
     * @param left 左边的索引
     * @param right 右边的索引
     * @param findVal 要查找的值
     * @return 如果找到就返回 下标 如果没有找到 就返回-1
     */
     
    public static int binarySearch(int[] arr,int left,int right,int findVal){
        //当left>right时候 说明递归结束:但是也没有找到
        if(left>right){
            return -1;
        }
        int mid=(left+right)/2;
        int midVal=arr[mid];
        if(findVal>midVal){
            //向右递归
            return binarySearch(arr,mid+1,right,findVal);
        }else if(findVal<midVal){
            //向左递归
            return binarySearch(arr,left,mid-1,findVal);
        }else {
            return mid;
        }

    }

代码3-当一个有序数组中有多个相同的数值,如何将所有的数值都查找到:

/**思路:
 * 1、在找到mid索引值时候,不要马上返回
 * 2、向mid的左边扫描,将所有满足xxx的元素的下标,加入到集合中ArrayList中
 * 3、向mid的右边扫描,将所有满足xxx的元素的下标,加入到集合中ArrayList中
 * 4、将ArrayList返回
 * /

//方法:
    /**
     *
     * @param arr 数组
     * @param left 左边的索引
     * @param right 右边的索引
     * @param findVal 要查找的值
     * @return 如果找到就返回 下标 如果没有找到 就返回-1
     */
     
    public static List binarySearch2(int[] arr, int left, int right, int findVal){
        //当left>right时候 说明递归结束:但是也没有找到
        if(left>right){
            return new ArrayList();
        }

        int mid=(left+right)/2;
        int midVal=arr[mid];

        if(findVal>midVal){
            //向右递归
            return binarySearch2(arr,mid+1,right,findVal);
        }else if(findVal<midVal){
            //向左递归
            return binarySearch2(arr,left,mid-1,findVal);
        }else {
            /**
             *  在找到mid索引值时候,不要马上返回
             */
            List IndexList = new ArrayList<>();
            //向左扫描
            int temp=mid-1; //也就是临时变量在mid左边的第一个位置
            while (true){
                if(temp<0||arr[temp]!=findVal){
                    break;
                }
                //否则 把temp放在集合中
                IndexList.add(temp);
                temp -=1;//temp左移动
            }

            IndexList.add(mid);//中间

            //向右边扫描
            temp=mid+1;
            while (true){
                if(temp>arr.length-1||arr[temp]!=findVal){
                    break;
                }
                //否则 把temp放在集合中
                IndexList.add(temp);
                temp +=1;//temp右移动
            }
            return IndexList;
        }
    }

结束语:

路漫漫其修远兮 吾将上下而求索

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值