二分查找

二分查找:

二分查找,是查找一个数的好方法。
优点在于:因为是折半查找,时间复杂度:O(logn)
缺点在于:查找的序列必须得是有序序列

对于二分查找,我们一般是查找一个数列的里的一个数,代码如下:
var
        n,i,l,r,mid,x:Longint;
        a:Array[1..100] of longint;
begin
        readln(n);
        for i:=1 to n do
                read(a[i]);
        readln(x);
        l:=1;
        r:=n;
        while l<=r do
        begin
                mid:=(l+r) div 2;
                if a[mid]=x then
                begin
                        writeln(mid);
                        halt;
                end;
                if x<a[mid] then
                        r:=mid-1
                else
                        l:=mid+1;
        end;
end.
这里的mid是指第几个数,这是最最普通的二分查找。在这里先复习一下,注意while条件的地方是l<=r。

但如果把问法改一下,改成在一个有序序列里有多少个数小于等于x?这时候能用二分查找吗?答案是:当然能!
但是二分查找是查找一个数,而这里只是说小于等于x,很有可能x不在这个有序序列里,这时候怎么办呢?

我们知道在二分里,mid是指查找的数的位置,l最后表示的是最后一个二分范围的最低值,r与l相反。而如果x有可能不在这个序列的话,我们是否可以判断出l的位置就是小于等于x的位置。

经过在草稿纸上的分析和推断可以得出,如果要判断出l的话,l的初值应该为0,而r的初值则要为n+1.当a[mid]<=x的时候,l=mid。
这里有几个地方需要注意:为什么是<=,而不是<?因为题目说了是<=x的也算,所以这里一定得加等于号.
然后为什么l是=mid,而不是=mid+1呢?因为如果是mid+1的话当a[mid]=x的时候就不正确了,所以如果是Mid的话,也是不会错的。
a[mid]>x的时候r=mid,最后l就是小于等于x的个数了。
贴贴代码吧:
l:=0; r:=n+1;
while l<r do
begin
<span style="white-space:pre">	</span>mid:=(l+r) div 2;
        if a[mid]<=x then l:=mid else r:=mid;
end;
inc(tot,l);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值