Java实现二分(折半)查找

二分查找适用于有序数据,使用前应先将数组按升序或降序排序。其思想如下:

  1. 设置三个指针 low、high、mid = (high + low)/ 2,分别指向数组最左侧数据、最右侧数据、中间数据。假设待查找关键字为 key
  2. 若 array[mid] == key,则查找成功,返回元素下标 mid
  3. 若 array[mid] > key,则 key 在区间 array[low] ~ array[mid - 1] 之间,继续在 array[low] ~ array[mid - 1] 之间使用二分查找法
  4. 若 array[mid] < key,则 key 在区间 array[mid + 1] ~ array[high] 之间,继续在 array[mid + 1] ~ array[high] 之间使用二分查找法
  5. 重复步骤 2 ~ 4 ,直至找到结果
public class BinarySearchDemo {
    // 非递归二分查找
    private static int nonRecursiveBinarySearch(int[] array, int key) {
        int high = array.length - 1, low = 0, mid;
        while (low <= high) {
            mid = low + (high - low) / 2;

            if (array[mid] == key)      // 若找到,则返回
                return mid;
            else if (array[mid] > key)  // 在左侧查找
                high = mid - 1;
            else                        // 在右侧查找
                low = mid + 1;
        }

        return -1;
    }

    // 递归二分查找
    private static int recursiveBinarySearch(int[] array, int low, int high, int key) {
        int mid = low + (high - low) / 2;
        if (array[mid] == key)          // 若找到,则返回
            return mid;
        else if (array[mid] > key)      // 在左侧查找
            return recursiveBinarySearch(array, low, mid - 1, key);
        else                            // 在右侧查找
            return recursiveBinarySearch(array, mid + 1, high, key);
    }

    private static void quickSort(int[] array, int left, int right) {
        // 数组长度为 0 或 1 时直接退出
        if (array == null || left > right || (array.length - 1 <= 0))
            return;

        int base = array[left]; // base:基准数据
        int i = left, j = right;// 让 i 指向数据最左侧,让 j 指向数据最左侧
        int temp;
        while (i != j) {
            // 从右向左搜寻小于 base 的数据
            while (array[j] >= base && i < j)
                j--;
            // 从左向右搜寻大于 base 的数据
            while (array[i] <= base && i < j)
                i++;

            // 交换搜寻到的数据
            if (i < j) {
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }

        // 将基准数放到中间的位置(基准数归位)
        array[left] = array[i];
        array[i] = base;
        /*temp = array[i];
        array[i] = array[left];
        array[left] = temp;*/
        // 一次排序结束,此时 base 左侧的数据全小于 base,右侧的数据全大于base

        quickSort(array, left, i - 1);// 快排 base 左侧数据
        quickSort(array, i + 1, right);// 快排 base 右侧数据
    }

    public static void main(String[] args) {
        int[] array = new int[] {196, 135, 129, 165, 105, 103, 116, 107, 156,
                101, 141, 144, 153, 107, 139, 114, 159, 152, 151, 127};
        int len = array.length;
        // 1 先将数组变为有序
        quickSort(array, 0, len - 1);

        System.out.println("数组元素为:");
        for (int i = 0; i < len; i++) {
            System.out.printf("%d ", array[i]);
        }
        System.out.println();

        int index = -1;
        // 2 非递归二分查找
        if ((index = nonRecursiveBinarySearch(array, 103)) == -1)
            System.out.println("元素不存在!");
        else
            System.out.printf("非递归二分查找-要查找元素下标为:%d\n", index);

        // 3 递归二分查找
        if ((index = recursiveBinarySearch(array, 0, len - 1, 151)) == -1)
            System.out.println("元素不存在!");
        else
            System.out.printf("递归二分查找-要查找元素下标为:%d\n", index);
    }
}
数组元素为:
101 103 105 107 107 114 116 127 129 135 139 141 144 151 152 153 156 159 165 196 
非递归二分查找-要查找元素下标为:1
递归二分查找-要查找元素下标为:13

Process finished with exit code 0
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值