大数据的树中如何快速验证数据是否存在

大数据的树中如何快速验证数据是否存在

在测试一个程序时,常常涉及到该程序中已输入的或未输入但将输入的数据,当这些数据很大时会对我们的测试带来一些困扰。我们总不能在驱动程序中直接键入这些数据,比如1,000个int型数据,它们的内存是4,000个字节;如果数据更大占用的内存更多。另外,如果数据是被存储在树这种数据结构中,查找是否已经输入某个数不仅有一定的空间复杂度还有时间复杂度。基于以上种种,一种简单的方法是使用位数组



位数组

位数组是用位的数量标记数据的数值。比如一个八位组的字节,它的位的数量一共有8个,那么它可以对应8个连续的数据。使用位的数量对应数值时,一定要注意数据是连续的,否则难以对应。

unsigned int bitArray[10] = { 0 };
// 标记 100 已存在
bitArray[ 100 / 32 ] |= ( 1 << ( 100 % 32 - 1 ) );

位数组实际上也是普通的数组,只不过我们是对位进行操作。对位进行操作时我们需要用到按位逻辑运算符,按位逻辑运算符的运算对象是整型数据,所以对位进行标记时我们要确定数组中哪一个元素。比如数值100对应第100个位,假设unsigned int型变量使用32位,那它就是被存储在第四个元素中。之后再确定是第四个元素中的第几个位,此时我们只需要求模即可,然后使用移位运算符做一些变动。需要注意的是一般位数组使用无符号整型,有符号整型会因为系统不同对高阶位影响不一样,因为我们要的仅仅是位的数量,当然也就不需要高阶位的变化影响,最好统一。



下面这个问题即验证在树中进行随机插入或删除操作的时间复杂度分析的准备工作。由于数据量足够大,直接在树中检查会增加负担:

假设你去验证通过随机插入或删除操作的一些问题。下面这个策略并非完全随机但足够接近。你建立一个具有\(N\)个元素的树,它是通过在\(1\)\(M=\alpha N\)间随机选择\(N\)个元素得到的。然后你执行\(N^2\)次先插入后删除的操作。假设存在例程randomInteger( a, b ),它返回介于ab之间的均匀随机整数。

(a)解释如何产生一个在\(1\)\(M\)之间的随机整数,它不在树中(即这个数是可以被随机插入到树中的)。使用\(N\)\(\alpha\)来评估这个操作的运行时间。

(b)解释如何产生一个在\(1\)\(M\)之间的随机整数,它在树中(即这个数可以被随机删除)。并评估运行时间。

(c)\(\alpha\)数值多少合适?为什么?

解:(a)对于随机整数的确立可以使用位数组,建立一个位数组B,若数字i已存在,则设置B[i]的值为1。因为,数组的索引表示元素,而位数组元素实际上是unsigned int型,所以可以建立一个类,索引不表示实际的元素,而是位的位置。

假设树中已经存在\(N\)个元素,那么不存在的元素数量是\(M-N\),随机产生的一个数是不存在于树中的概率是\((M-N)/M\)(几何分布)。因此,这个数是不存在于树中的期望值是\(M/(M-N)\)(因为是几何分布,所以这里的数学期望是概率的倒数,因为这是平均情况下的平均次数),即\(\alpha / (\alpha - 1)\)。用这个期望值标定时间复杂度,得到该操作的运行时间是\(O(\alpha / (\alpha - 1))\)

(b)随机整数的确立同(a)相同,建立一个位数组。随机产生的一个数在树中的概率符合几何分布,其概率是\(N/M\),那么它的期望值是\(M/N\),即\(\alpha\)。标定时间复杂度的结果是\(O(\alpha)\)

(c)题目要求进行插入和删除对操作,\(\alpha\)取值取决于插入和删除总运行时间。根据(a)与(b)可知总运行时间是:

\[T = \frac{\alpha}{\alpha - 1} + \alpha \]

很显然,这是一个关于\(\alpha\)的一个函数,不妨令其为\(f(\alpha)\)。对其求导后得到:

\[f'(\alpha) = 1 - \frac{1}{(\alpha - 1)^2} \]

\(\alpha = 2\)时,得到最小值:

\[f(\alpha)_{min}|_{\alpha = 2} = 4 \]

所以,\(\alpha\)取值为\(2\)时合适,因为此时运行时间最小。

posted @ 2025-09-06 18:46  永恒圣剑  阅读(5)  评论(0)    收藏  举报