今天是开通博客后第一次做算法导论习题呢。。。
首先是算法导论散列表11.1的答案。
11.1-1 假设一动态集合S用一个长度为m的直接寻址表T来表示,请给出一个查找S中最大元素的过程,你所给的过程在最坏情况下的运行时间是多少?
第一题,很简单按照我的理解这题就是没有卫星数据,意味着key值就是数值大小也是下标,那我们就从下往上遍历整个表,直到找到一个非空的slot为止,这很好理解,下标越大值就越大,但是最糟糕情况下就需要O(n)的渐近时间,发生在空表或数据在表头处这种情况。
11.1-2 使用bit vector来做一个没有satellite data的直接寻址表,要求O(1)的字典操作时间。
看到这题想到剑指offer还是编程之美里面的一道题,大意就是需要在一段非常大的不重复整数中寻找一个数有没有,解决方案就是bit vector。
开始分析,首先,先决条件:不重复整数,应该还要正整数,这样的整数在所属集合中独一无二,而每个位在二进制中也是独一无二的,因为位置是不会重合的,所以每一个为对应一个整数,而整个集合使用一个大数组做为存储,假设我们一共拥有1024个整数,并且我们一个字节8各位,那么我们使用char[1024/8] 的数组,然后使用位运算判断每个位的0或1从而确认数据的存在,大致思路就是这样。
可以轻易的得到key/8就是数组的下标,而key%8就是在每个字节中的顺序,由于8为2的幂,我们可以使用位运算key>>3,key&(7)来得到所需要的值
代码如下
#include <iostream>
#include <cmath>
#include <vector>
#include <assert.h>
class BitVector
{
public:
BitVector(int upperLimit=1024)
: Bit(8),
Vector(roundUp(upperLimit)/8),
offset(3)
{
//std::cout<<Vector.capacity()<<std::endl
}
bool find(size_t key)
{
assert(key < 1024);
return Vector[key >> offset] & (1 << (key & (Bit - 1)));
}
void insert(size_t key)
{
assert(key < 1024);
Vector[key >> offset] |= (1 << (key & (Bit -