算法设计与分析——折半查找(Java)

在传统的算法设计技术的分类中,折半查找属于分治技术的典型应用。但是,由于折半查找与待查值每比较一次,根据比较结果使得查找的区间减半,所以,折半查找应该属于减治技术的成功应用。

【问题】应用折半查找方法在一个有序序列中查找值为 k 的记录。若查找成功,返回记录 k 在序列中的位置,若查找失败,返回失败信息。

【想法】折半查找 (binary search) 利用了记录序列有序的特点,其查找过程是:取有序序列的中间记录作为比较对象,若给定值与中间记录相等,则查找成功;若给定值小于中间记录,则在中间记录的左半区继续查找;若给定值大于中间记录,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所查找的区域无记录,查找失败。其减治思想如下图所示。

例如,在有序序列 {7,14,18,21,23,29,31,35,38} 中查找 18 的过程如下图所示。

【算法】折半查找算法用伪代码描述如下。

算法:折半查找 BinSearch

输人:有序序列 {r_{1}r_{2},...,r_{n}},待查值 k

输出:若查找成功,返回记录 k 的位置,若查找失败,返回失败标志 0

1.设置初始查找区间:low=1;high=n;

2.测试查找区间 [ low,high ] 是否存在,若不存在,则查找失败;否则

3.取中间点 mid = ( low+high ) / 2;比较 k 与 r_{min},有以下三种情况:

    3.1 若 k<r_{min},则 high=mid-1;查找在左半区进行,转步骤2;

    3.2 若 k>r_{min},则 low= mid+1;查找在右半区进行,转步骤2;

    3.3 若 k=r_{min},则查找成功,返回记录在表中位置 mid。 

【算法分析】折半查找的过程可用判定树来描述,判定树中的每个结点对应有序序列中的一个记录,结点的值为该记录在有序序列中的位置。下图给出了具有11个结点的判定树。

可以看到,查找某个记录的过程,即是判定树中从根结点到该记录结点的路径,和待查值的比较次数等于该记录结点在树中的层数。为便于讨论,以深度为 k 的满二叉树 (n=2^{k-1}-1) 为例,假设每个记录的查找概率相等,即 p_{i}=1/n(1≤ i ≤n),而树的第 i 层上有 2^{i-1} 个结点,因此,折半查找的平均查找长度为: 

所以,折半查找的时间复杂性为O(log_{2}n)。
【算法实现】折半查找算法用JAVA语言描述如下:

public class HalfFind {
    public static void main(String[] args)
    {
        int r[]={7, 14, 18, 21, 23, 29, 31, 35, 38};
        int i=BinSearch1(r,9,18);
        System.out.println("在数组中的下标是:"+i);
    }

    static int BinSearch1(int r[], int n, int k)
    {
        int low = 0, high = n - 1;               //设置查找区间,注意数组下标从0开始
        int mid;
        while (low <= high)                //当区间存在时
        {
            mid = (low + high) / 2;
            if (k < r[mid])	high = mid - 1;
            else	if (k > r[mid]) low = mid + 1;
            else return mid;                      //查找成功,返回元素序号
        }
        return 0;                                  //查找失败,返回0
    }

}

运行结果如下:

from:算法设计与分析(第2版)——王红梅 胡明 编著——清华大学出版社

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值