二分查找算法--递归式与非递归式两种方式实现

     二分查找法是将数据折半,小于中间值就找小于中间值区间的数据,大于中间值就找大于中间值区间的数据,这样就大大的增加了效率,可以更快速的查找到指定数据,就是缺点必须是有序的,但是现在实现排序很方便也很高效倒也不是瓶颈,无序的话二分查找也体现不了其意义所在,那么接下来就详细讲解二分查找

1.二分查找概念

二分查找实际上是不断地将有序数据集进行对半分割,并检查每个分区地中间元素。

 

2.二分查找特点

  1. 二分查找操作地数据集是一个有序的数据集
  2. 二分查找能应用于任何类型的数据,只要能将这些数据按照某种规则进行排序
  3. 当待搜索的集合是相对静态(静态指的是不是动态的数据)的数据集时,此时使用二分查找是最好的选择。
  4. 复杂度是O(log n),n为要查找的元素个数

3.二分查找原理图

 

 
此实现是通过low和high的变量值控制循环来查找
1.首先将low设置为0,high设置为数组长度-1
2.循环迭代的过程中将middle(中间值)设置为low和high区域的中间值
3.判断如果目标值比middle元素值小,那么high移动到middle前一个位置元素上
4.判断如果目标值比middle元素值大,那么low移动到middle后一个位置元素上。
5.依次类推,直到判断相等,值找到。

4.二分查找法代码实现
 

package com.test.binarySearch;

/**
 * 非递归二分查找和递归二分查找的demo
 * 二分查找:二分查找必须是有序的集合,进行对半分割查找,并检查每个分区地中间元素
 * 此实现是通过low和high的变量值控制循环来查找
 * 1.首先将low设置为0,high设置为数组长度-1
 * 2.循环迭代的过程中将middle(中间值)设置为low和high区域的中间值
 * 3.判断如果目标值比middle元素值小,那么high移动到middle前一个位置元素上
 * 4.判断如果目标值比middle元素值大,那么low移动到middle后一个位置元素上。
 * 5.依次类推,直到判断相等,值找到。
 *
 * @Author df
 * @Date 2019/9/2 9:39
 * @Version 1.0
 */
public class towBinarySearch {
    public static void main(String[] args) {
        Integer[] intArray = {23, 30, 44, 56, 60, 61};
        System.out.println(NonRecursive(intArray, 56));
        //System.out.println(recursive(intArray, 0, intArray.length - 1, 30));
    }


    /**
     * 非递归形式的二分查找
     *
     * @param intArray 整型数组
     * @param keyValue 需要比较的数
     * @return
     */
    public static int NonRecursive(Integer[] intArray, int keyValue) {
        // 第一个位置.
        int low = 0;
        // 最高位置,数组长度-1,因为下标是从0开始的。
        int high = intArray.length - 1;
        while (low <= high) {
            // 中间位置计算,low+最高位置减去最低位置,右移一位,相当于除2.也可以用(high+low)/2
            int middle = low + ((high - low) >> 1);
            // 与最中间的数字进行判断,是否相等,相等的话就返回对应的数组下标。
            if (keyValue == intArray[middle]) {
                return middle;
            } else if (keyValue < intArray[middle]) {
                // 如果比较数小于当前中间位置的话移动最高层的“指针”
                // 此处移动high高指针是因为比对的值小于,就需要查找左半部分的数据
                high = middle - 1;
            } else {
                low = middle + 1;
            }
        }
        return -1;
    }

    /**
     * 递归形式的二分查找
     *
     * @param intArray 整型数组
     * @param low 最开始的下标
     * @param high 最高的坐标
     * @param keyValue 需要比较的数
     * @return
     */
    public static int recursive(Integer[] intArray, int low, int high, int keyValue) {
        if (low <= high) {
            int middle = (low + high) / 2;
            // 与基准值进行比较,相等就是找到想要的数据
            if (keyValue == intArray[middle]) {
                return middle;
            }
            // 小于基准值右指针向左移动一格
            if (keyValue < intArray[middle]) {
                return recursive(intArray, low, middle - 1, keyValue);
            }
            // 大于基准值左指针向右移动一格
            if (keyValue > intArray[middle]) {
                return recursive(intArray, middle + 1, high, keyValue);
            }
        } else {
            return -1;// 什么都查找不到的话。
        }
        return -1;
    }
}
二分查找法就介绍这么多,下次见
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值