折半查找(对半查找、二分查找)

本文详细介绍了折半查找算法的工作原理,包括其在有序数组中的应用,以及递归和非递归两种实现方式。重点讨论了数据结构要求、性能分析,如判定树和平均查找长度。通过实例演示了在升序数组中寻找比给定值小的最大元素的方法。
摘要由CSDN通过智能技术生成

1.折半查找:在有序表(假设为递增)中

(1)取中间记录作为比较对象,若给定值与中间记录相等,则查找成功;

(2)若给定值小于中间记录,则在有序表的左半区继续查找;

(3)若给定值大于中间记录,则在有序表的右半区继续查找。

(4)不断重复上述过程,直到查找成功,或查找区域无记录,查找失败

2.折半查找的条件:

(1)数据必须有序

(2)顺序存储结构(数组)

3.非递归和递归两种方法:

#include <iostream>

using namespace std;
class LineSearch{
public:
    LineSearch();
    LineSearch(int a[],int n);
    int BinSearch1(int k);
    int BinSearch2(int low,int high,int k);
private:
    int data[10];
    int length;
};
LineSearch::LineSearch(){
    length=0;
}
LineSearch::LineSearch(int a[],int n){
    length=n;
    for(int i=0;i<n;i++)
        data[i]=a[i];
}
int LineSearch::BinSearch1(int k){
    int mid,low=1,high=length;
    while(low<=high){
        mid=(low+high)/2;
        if(data[mid]>k)
            high=mid-1;
        else if(data[mid]<k)
            low=mid+1;
        else
            return mid;
    }
    return 0;
}
int LineSearch::BinSearch2(int low,int high,int k){
    int mid;
    if(low>high)//递归的边界条件
        return 0;
    else{
        mid=(low+high)/2;
        if(data[mid]>k)
            BinSearch2(low,mid-1,k);
        else if(data[mid]<k)
            BinSearch2(mid+1,high,k);
        else
            return mid;
    }
}
int main()
{
    //通常把下标为0处空着
    int a[10]={0,5,12,15,16,18,22,24,30,36};
    LineSearch ls(a,10);
    int x=ls.BinSearch1(10);
    if(x)
        cout<<"查找成功,查找的数字的下标是"<<x<<endl;
    else
        cout<<"查找失败"<<endl;

    int y=ls.BinSearch2(1,9,12);//注意数组越界问题
    if(y)
        cout<<"查找成功,查找的数字的下标是"<<y<<endl;
    else
        cout<<"查找失败"<<endl;
    return 0;
}

  • 为避免溢出,mid也可以用mid=right+(left-right)/2表示

4.性能分析

(1)折半查找判定树:

  • low>high时,判定树为空
  • low<=high时,判定树的根节点是mid=(low+high)的数据。根结点的左子树是r[low]~r[mid-1]对应的判定树,根结点的右子树是r[mid+1]~r[high]对应的判定树。

最终由折半查找判定树可知,成功次数=表长,失败次数=表长+1

(2)平均查找长度只与表长有关,表长一定时,成功和失败的平均查找长度也是固定的。

例题一:

在包含n个元素,升序排列的数组a[n]中寻找比p小的、下标最大的元素

#include <iostream>

using namespace std;
//二分查找:在升序排列的数组a[n]中寻找比p小的、下标最大的元素
int BinSearch(int a[],int n,int p){
    int left=0;
    int right=n-1;
    int flag=-1;
    while(left<=right){
        int mid=left+(right-left)/2;
        if(a[mid]<=p){
            left=mid+1;
            flag=mid;
        }
        else
            right=mid-1;
    }
    return flag;
}
int main()
{
    int a[5]={2,4,6,8,10};
    int x=BinSearch(a,5,7);
    cout<<a[x]<<endl;
    return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值