二分查找

在 N 个键的有序数组中进行二分查找最多需要 (lgN) + 1 次比较(无论是否成功)

向大小为 N 的有序数组中插入一个新的元素在最坏情况下需要访问 2 * N 次数组,因此向一个空符号表中插入 N 个元素在最坏情况下需要访问 N2 次数组

 

import java.util.ArrayList;

public class BinarySearch {//假设数组从小到大排序

    //递归法,left初始值传入0,right初始值传入array.length - 1
    public static ArrayList<Integer> recurseBinarySearch(int[] array, int left, int right, int find) {
        if (left > right || array == null || array.length == 0 || find < array[left] || find > array[right]) {
            return new ArrayList<>();//数组为空或find不存在
        }
        int midIndex = left + ((right - left) >> 1);//中间值的索引
        int mid = array[midIndex];//中间值
        if (find > mid) {//find大于中间值,向右递归
            return recurseBinarySearch(array, midIndex + 1, right, find);
        } else if (find < mid) {//find小于中间值,向左递归
            return recurseBinarySearch(array, left, midIndex - 1, find);
        } else {//find == mid,找到了该值
            ArrayList<Integer> indexList = new ArrayList<>();//存放符合find的元素的索引
            indexList.add(midIndex);//中间值本身的索引放入indexList中
            int temp = midIndex - 1;
            while (true) {//中间值向左寻找相同值的索引
                if (temp < 0 || array[temp] != find) {
                    break;
                }
                indexList.add(temp--);
            }
            temp = midIndex + 1;
            while (true) {//中间值向右寻找相同值的索引
                if (temp > array.length - 1 || array[temp] != find) {
                    break;
                }
                indexList.add(temp++);
            }
            return indexList;
        }
    }

    //循环法
    public static ArrayList<Integer> circleBinarySearch(int[] array, int find) {
        int left = 0;
        int right = array.length - 1;
        ArrayList<Integer> indexList = new ArrayList<>();
        if (array == null || array.length == 0) {
            return indexList;//数组为空
        }
        while (left <= right) {
            int midIndex = left + ((right - left) >> 1);//中间值的索引
            int mid = array[midIndex];//中间值
            if (find > mid) {//向右查找
                left = midIndex + 1;
            } else if (find < mid) {//向左查找
                right = midIndex - 1;
            } else {//find == mid,找到了该值
                indexList.add(midIndex);
                int temp = midIndex - 1;
                while (true) {//中间值向左寻找相同值的索引
                    if (temp < 0 || array[temp] != find) {
                        break;
                    }
                    indexList.add(temp--);
                }
                temp = midIndex + 1;
                while (true) {//中间值向右寻找相同值的索引
                    if (temp > array.length - 1 || array[temp] != find) {
                        break;
                    }
                    indexList.add(temp++);
                }
                return indexList;
            }
        }
        return indexList;//find不存在
    }
}

 

posted @   半条咸鱼  阅读(9)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示