在严奶奶版的《数据结构》一书中, 严奶奶引用了别的书的观点: 在顺序查找时(设表长>=1000), 引入监视哨兵, 可以减少几乎一半的查询时间。
理论上,引入监视哨兵, 的确可以优化时间。来测试一下, 看看引入监视哨兵的前后对比:
#include <iostream>
#include <ctime>
#include <windows.h>
#define N 100001
#define TIMES 1000
using namespace std;
int find_v1(int a[], int n, int k)
{
int i = 1;
for(; i < n && a[i] != k; i++);
return (i == n ? 0 : i);
}
int find_v2(int a[], int n, int k) // 带监视哨兵
{
a[0] = k;
int i = n - 1;
for(; a[i] != k; i--);
return i;
}
void init_array(int a[], int n)
{
int i = 1;
for(; i < n; i++) // a[0]处不存元素,空出来
{
a[i] = i;
}
}
int main()
{
int j = 0;
int a[N];
init_array(a, N);
clock_t start, finish;
int k = -1; // 待查找的数, 这里定为-1, 就是假定找不到这个k
// 不带哨兵
{
start = clock();
for(j = 0; j < TIMES; j++)
find_v1(a, N, k);
finish = clock();
cout << finish - start << endl;
}
// 带哨兵
{
start = clock();
for(j = 0; j < TIMES; j++)
find_v2(a, N, k);
finish = clock();
cout << finish - start << endl;
}
return 0;
}
可以看到,引入监视哨兵, 每次循环少了边界判断(i < n), 实际运行了多次, 其中一次结果的数据是(单位是毫秒):
453
381
多次反复测试, 均表明引入监视哨兵确实有好处, 但从我的测试来看, 远远达不到一半的优化。 当时, 看到严奶奶那个引用别人的论断时, 我就怀疑, 严奶奶应该没有实际测试过。
在严奶奶的书中, 好几个地方都说“经验表明”, 呵呵。 要么给出证明, 要么给出大量的经验数据(包括各种测试条件的设置)。 想引用别人的书也可以, 但别人的书也得经验数据齐全啊, 否则这有点像多级指针, 指针指一指, 责任全抛开。
若是仅仅一句“经验表明”, 就有点呵呵哒了。
不多说。
扫描二维码关注公众号,回复:
2732582 查看本文章