位图标记 二分查找 位二分

在具有n个元素的表中进行查找,顺序查找平均要进行n / 2(所有可能求和除以n)次比较。而用二分查找的比较次数不会超过logn(底数为2)。O(logn)与O(n)在系统性能上可以导致很大的差距。如果有线性查找的程序变得很慢了(数据更大了),二分查找查找往往可以排除这个瓶颈。而且二分查找并不只是只应用于已排序的数组(具有二分性质的可能都可以使用二分查找)。


1 问题

在一个存在n个m位整数的文件中,找出一个在此文件中不存在的m位整数。(n < 2^m)。随m值在8,16,32值上的变化,n的值也可能使这个文件的数据大小为kb,M,G级别大小。


对于文件中的整数,可以用位图数据结构(char bit[2^m + 1], 每元素初始值都为0)来标识文件中的每一个整数,对从文件中读到的每一个整数i都采用bit[i] = 1来标识。读取完文件中的数据后,那些bit数组元素值为0 的下标就是文件中不存在的整数。


采用位图数据结构解决这个方法是需要主存至少需要2^m + 1字节内存,且当文件中有负数时位图数据结构(bit数组)还会越界。


2 计算机中数据的存储规律

为了使用二分查找法解决这个问题。明锐眼光的前辈利用了数值在计算机内部存储的规律对n个m位的整数数进行二分。这个规律是这样的: 对于一个m位的整数,最高位为1和最高位为0所对应的整数的个数相同(补码的-0用来表示-2^(m-1))。同理,对于次高位(此时不存在符号位)为1和次高位为0所对应的整数个数也是相同的……又1位构成的整数的最高位为1和最高位为0对应的整数个数也是一样的。可表示成以下规律:

m –1……i……10
在大于i的所有位相同的情况下,i = 1和i = 0时分别对应的整数个数相同:都由[0…i)来决定。(0 <= i <= m - 1)。


3 确定缺少整数

(1) 确定缺少整数的范围(文件)

由2中的规律可以知道,如果问题中的文件只少了一个整数即n + 1 = 2^m时,少的这个整数的最高位要么为1,要么为0。在这个文件中的文件根据最高位将数字分到两个文件中后,一定有一个文件中的数的个数要比另一个文件要少1。此时就可以确定缺少的整数是位于哪个文件中。然后根据整数的次高位再对这个文件分为次高位为1和为0的两个文件,再根据两个文件的数的个数判断缺少的整数存在在哪一个文件中……最终确定缺少的那个整数:当文件中只存在唯一一个整数数时,若此数最后一位为1(0),则缺少的整数的除了最后一位为0(1),其余位同文件中整数的其余位。


设每次将整数当前最高位为0的整数写入A文件,为1的写入B文件中。当然,对于n +1< 2^m即文件中不只是少了一个整数的情况下,将会有不同的情况:

  •  number(A) = number(B),此时两个文件都有缺少的数。若只查找缺少的一个整数,则此时可随机的选择一个文件进行后续操作。
  • number(A) <  number(B),此时B中可能有缺少的整数(若number(B)小于父文件的整数个数的二分之一时),而A文件中一定缺少了某个整数,此时可选择A文件进行后续操作。

(2) 确定缺少的整数

如果只为找任意一个缺少的整数,则经(1)中的操作后,最终会得到只包含一个数的文件。若这个数为*******0(1),则却少的整数一定为*******1(0)。


4 程序分析

用以上算法实现的二分查找法解决问题的程序在时间和空间之上都具有众多的好处。程序流程:顺序读当前文件中的一个m位整数到内存中,分析此m位整数当前最高位的符号,将其写入对应的文件中,…….,直到操作结束找到一个缺失的整数。

  •  内存空间:对于存储文件中的数据,程序执行过程中都只需要用m位(理论,还要考虑内存对齐)内存。
  • 代码空间:代码可分为3小块,读、分析当前最高位、写。
  • 时间复杂度:以以上内存空间和代码空间执行logn次,得到时间复杂度为O(logn)。

5 总结

采用位二分也有限制,比如要求所有的整数都是m位。但最重要的是为使用二分查找法提供了启发:二分查找不仅局限的使用在经排序的序列之上,一般只要明确以下三个可行条件:

  • 二分查找的范围;
  • 二分查找元素的存在形式;
  • 探测方式。

如果这三个条件满足二分查找的规律并最终能够查找到元素就可以享受二分查找的时间复杂度为O(logn)的快速。

SNote Over。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值