二分查找算法

二分查找算法:是对有序数组进行二分查找

思路分析:

1 首先确定该数组的中间的下标
mid = (left +right) / 2

2 然后让需要查找的数findVal和arr[mid]比较

2.1 findVal > arr[mid] ,说明你要查找的数在mid的右边,因此需要递归的向右查找
2.2 findVal < arr[mid],说明你要查找的数在mid的左边,因此需要递归的向左查找
2.3 findVal = arr[mid],说明你找到了你要找的数,就返回就好

3 什么时候结束递归呢

3.1 找到就结束喽
3.2 递归完整个数组,仍然没有找到findVal,也需要结束递归,当left > right非时候
Version1:当有序数组中没有重复元素的时候
注意点:使用递归方法的结束条件要准备好
思考:还有没有其他的方法呢?
package com.aaron.algorithm.Search;

//注意:二分查找是针对的有序数组
public class BinarySearch {
    public static void main(String[] args) {
        int arr[] = {1, 22, 33, 55, 88};

        int resIndex = binarySearch(arr,0 ,arr.length - 1,2);
        System.out.println("索引为"+resIndex);

    }

    /**
     * 二分查找
     * @param arr 原始有序数组
     * @param left left index
     * @param right right index
     * @param findVal 要找的值
     * @return 如果找到就返回下标;没有,返回-1
     */
    private static int binarySearch(int[] arr, int left, int right, int findVal) {
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        //当left>right时,说明递归整个数组都没有找到,那么返回-1
        if (left > right) {
            return -1;
        }

        //向左右递归
        if(findVal > midVal) {
            return binarySearch(arr, mid + 1, right ,findVal);
        } else if (findVal <midVal) {
            return binarySearch(arr, left, mid - 1,findVal);
        } else {
            return mid;
        }
    }
}

Version2:在有序数组中将含有多个相同元素的数组下标加入到集合中
package com.aaron.algorithm.Search;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BinarySearch {
    public static void main(String[] args) {
        int arr[] = {1, 22, 33, 55, 88, 88, 88, 100};

//        int resIndex = binarySearch(arr,0 ,arr.length - 1,88);
//        System.out.println("索引为"+resIndex);
        List<Integer> resIndex = binarySearch2(arr, 0, arr.length - 1, 88);
        System.out.println(resIndex);

    }


    /**
     * 二分查找
     *
     * @param arr     原始有序数组
     * @param left    left index
     * @param right   right index
     * @param findVal 要找的值
     * @return 如果找到就返回下标;没有,返回-1
     */
    private static int binarySearch(int[] arr, int left, int right, int findVal) {
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        //当left>right时,说明递归整个数组都没有找到,那么返回-1
        if (left > right) {
            return -1;
        }

        //向左右递归
        if (findVal > midVal) {
            return binarySearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) {
            return binarySearch(arr, left, mid - 1, findVal);
        } else {
            return mid;
        }
    }

    /**
     * 二分查找
     *
     * @param arr     原始有序数组
     * @param left    left index
     * @param right   right index
     * @param findVal 要找的值
     * @return 如果找到就返回下标;没有,返回-1
     * <p>
     * 需求:在有序数组中将含有多个相同元素的数组下标加入到集合中
     * 思路分析:
     * 1、在找到mid索引值,不要马上返回
     * 2、向mid索引值的左边扫描,将所有满足findVal的元素下标,加入到集合的ArrayList中
     * 3、向mid索引值的右边扫描,将所有满足findVal的元素下标,加入到集合的ArrayList中
     * 4、将ArrayList返回
     */
    private static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        //当left>right时,说明递归整个数组都没有找到,那么返回-1
        if (left > right) {
            return new ArrayList<>();
        }

        //向左右递归
        if (findVal > midVal) {
            return binarySearch2(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) {
            return binarySearch2(arr, left, mid - 1, findVal);
        } else {
            /** 思路分析:
             * 1、在找到mid索引值,不要马上返回
             * 2、向mid索引值的左边扫描,将所有满足findVal的元素下标,加入到集合的ArrayList中
             * 3、向mid索引值的右边扫描,将所有满足findVal的元素下标,加入到集合的ArrayList中
             * 4、将ArrayList返回
             */
            ArrayList<Integer> resIndexList = new ArrayList<>();

            int temp = mid - 1;
            while (true) {
                if (temp < 0 || arr[temp] != findVal) {
                    break;
                }

                resIndexList.add(temp);
                temp -= 1;
            }
            resIndexList.add(mid);

            //向mid索引值的左边扫描,将所有满足findVal的元素下标,加入到集合的ArrayList中
            temp = mid + 1;
            while (true) {
                if (temp > arr.length - 1 || arr[temp] != findVal) {
                    break;
                }

                resIndexList.add(temp);
                temp += 1;
            }
            return resIndexList;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值