搜索算法----二分查找(折半查找)

本文详细介绍了二分查找算法的工作原理及其实现方法,包括非递归和递归两种实现方式,并探讨了其适用场景和时间复杂度。适用于有序列表的高效查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分查找的先决条件:序列是有序的升序排列的。
查找的效率较高,但是只适用于有序表,且限于顺序存储结构,对线性链表无法有效的进行查找,
还有二分查找在一些特殊情况下,其查找效率很低,如查找元素是数列中的第一个元素和最后一个元素。

二分查找的时间复杂度是O(log(n)),最好的情况是指针mid指的第一个数就是要找的值,
最坏的情况的所找的值是第一个或最后一个数,最坏情况下的时间复杂度是O(n)。

中心思想是取中间和比较。
适用场景:不经常变动而查找频繁的有序列表。

二分查找涉及到2个方面,一方面是找到目标元素第一次出现的位置;另一方面是找到目标元素最后一次出现的位置。可以使用递归方式和非递归方式实现。

java非递归实现:

import java.util.Arrays;

public class binarySearchTest {

    //寻找指定元素最后一次出现的位置
    public static int binarysearch(int[] a, int left, int right, int value) {

        int middle = 0;
        if (a.length == 0 || left > right) {
            return -1;
        }

        while (left <= right) {
            middle = (left + right) / 2;

            if(a[middle]>value){
                right=middle-1;
            }
            else {
                left=middle+1;
            }
        }

        if(a[right]==value)
            return right;
        return -1;
    }

    //寻找指定元素第一次出现的位置
    public static int binarysearch1(int[] a, int left, int right, int value) {

        int middle = 0;
        if (a.length == 0 || left > right) {
            return -1;
        }

        while (left <= right) {
            middle = (left + right) / 2;

            if(a[middle]>=value){
                right=middle-1;
            }
            else {
                left=middle+1;
            }
        }

        if(a[left]==value)
            return left;
        return -1;
    }

    public static void main(String[] args) {
        int[] array = { 7,4,2,2,2,1,4,1};
        Arrays.sort(array);
        int value = 2;
        int result = binarysearch(array, 0, array.length - 1, value);
        int result1 = binarysearch1(array, 0, array.length - 1, value);
        System.out.print(result);
        System.out.print("\n"+result1);
    }

}

使用递归方法实现:

package test;

import java.util.Arrays;
public class binarySearchTest2 {

    //查找目标元素最后一次出现的位置
    public static int binarySearchLast(int[] a, int left, int right, int value) {

        if (left <= right && a.length != 0) {
            int middle = (left + right) / 2;

            if (a[middle] > value) {
                return binarySearchLast(a, left, middle - 1, value);
            }

            else if (a[middle] <= value) {
                return binarySearchLast(a, middle + 1, right, value);
            }
        }
        if (a[right] == value) {
            return right;
        }
        return -1;

    }

    //查找目标元素第一次出现的位置
    public static int binarySearchFirst(int []a,int left,int right,int value) {

        if(left<=right&&a.length!=0){
            int middle=(left+right)/2;
            if(a[middle]>=value){
                return binarySearchFirst(a, left, middle-1, value);
            }
            else {
                return binarySearchFirst(a, middle+1, right, value);
            }
        }
        if(a[left]==value){
            return left;
        }

        return -1;
    }


    public static void main(String[] args) {
        int[] array = { 1, 2, 2, 5, 2, 2 };
        Arrays.sort(array);
        int value = 2;
        int result1 = binarySearchLast(array, 0, array.length - 1, value);
        System.out.print(result1);
        int result2 = binarySearchFirst(array, 0, array.length - 1, value);
        System.out.print("\n"+result2);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值