• 算法与数据结构



     

    二分法

    二分法的前提是 在有序数组中,所以如果一个数组是无序的,我们要先把无序数组变为有序数组。

    二分查找的思路分析:(假设该数组为自左向右从小到大)

    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],说明找到,就返回

    // 什么时候我们需要结束递归呢?

    有两种情况:

    1.找到数就结束递归

    2.递归完整个数组,仍然没有找到 findVal ,也需要结束递归,即 left > right 就需要退出。

    代码实现(基本写法):

    题目:请对一个有序数组进行二分查找{1, 8, 10, 89, 1000, 1234},输入一个数看看该数组是否存在该数,并且求出下标,否则就提示,没有这个数。

    /**
     * @program: Julih
     * @description:
     * @author: wangxp
     * @create: 2019-11-18 21:40
     */
    // 注意: 使用二分查找的前提是,数组是有序的.
    public class BinarySearch {
    
        public static void main(String[] args) {
            int arr[] = {1, 8, 10, 89, 1000, 1234};
            int resIndex = binarySearch(arr, 0, arr.length - 1, 1111);
            System.out.println("resIndex is " + resIndex);
        }
    
        /**
         * 二分查找算法
         * @param arr   数组
         * @param left  左边的索引
         * @param right 右边的索引
         * @param findVal   要查找的值
         * @return  如果找到就返回下标,否咋返回-1
         */
        public static int binarySearch(int[] arr, int left, int right, int findVal){
    
            if (left > right){  // 如果没有找到,就直接返回 -1
                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;
            }
        }
    }

    二分查找(升级版):

    题目:{1, 8, 10, 89, 1000, 1000,1000,1234},当一个有序数组中,有多个相同数值时,如何将所有的数值都查找到,比如这里的1000?

    /**
     * @program: Julih
     * @description:
     * @author: wangxp
     * @create: 2019-11-18 21:40
     */
    // 注意: 使用二分查找的前提是,数组是有序的.
    public class BinarySearch2 {
    
        public static void main(String[] args) {
            int arr[] = {1, 8, 10, 89, 1000, 1000, 1000, 1234};
            List<Integer> resIndexList = binarySearch(arr, 0, arr.length - 1, 1000);
            System.out.println("resIndexList is " + resIndexList.toString());
        }
    
        /**
         * 二分查找算法
         * @param arr   数组
         * @param left  左边的索引
         * @param right 右边的索引
         * @param findVal   要查找的值
         * @return  如果找到就返回下标,否咋返回-1
         */
        public static List<Integer> binarySearch(int[] arr, int left, int right, int findVal){
    
            if (left > right){  // 如果没有找到,就直接返回 -1
                return new ArrayList<Integer>();
            }
            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{
                // 当已经找到的时候,先不退出,
                List<Integer> resIndexList = new ArrayList<Integer>();
                // 向mid 索引值得左边扫描,将与findVal相等的值得下标,加入到ArrayList中.
                int temp = mid - 1;
                while (true){
                    if (temp < 0 || arr[temp] != findVal){  // 退出
                        break;
                    }
                    // 否则,将 temp 放入到 resIndexList中
                    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;
                    }
                    // 否则,将 temp 放入到 resIndexList中
                    resIndexList.add(temp);
                    temp += 1;  // 右移
                }
                return resIndexList;
            }
        }
    }

      

  • 相关阅读:
    「密码不符合策略要求」的解决方案——在「secpol.msc」中禁用「密码必须符合复杂性要求」
    IIS7远程桌面管理(iis7.net出品)
    VNC远程控制客户端和服务端下载(VNC可跨平台)
    路由跟踪(可视化)——Best Trace
    定时任务工具——Shutdown it!(模拟鼠标点击、到时间后执行复制、消息提示等功能)
    FastCopy 提示「Can't alloc memory(misc stat)(内存资源不足,无法处理此命令。8) :」的解决方案
    博客园测试
    支持定时任务(上传/下载)的FTP工具
    Animate CC 由原Adobe Flash Professional CC 更名得来,支持html5
    开源的拼音输入法
  • 原文地址:https://www.cnblogs.com/Night-Watch/p/11885925.html
Copyright © 2020-2023  润新知