来自《数据结构》 严蔚敏 吴伟民 著, 1986 版。
教材上在查询时,用了一个小技巧,就是监视哨。并说,实践验证当n>1000时,效率提高几乎一倍以上。见原书P221。 笔者为此做了实验,发现在目前的硬件情况下,性能没有教材说的那么明显。估计是那个时候,计算即硬件计算速度有限。但是当数目很大时,这个作用还是挺明显的。C#代码如下
private void btnGuard_Click(object sender, EventArgs e)
{
// Test the role of the guard in searching process
var n = 100000000;
int[] dat = new int[n];
var i = 1;
while (i < n)
{
dat[i] = i;
i++;
}
DateTime startTime = DateTime.Now;
NoGuardSearchFor(dat, -1);
DateTime endTime = DateTime.Now;
var ts1 = endTime - startTime;
startTime = DateTime.Now;
NoGuardSearchWhile(dat, -1);
endTime = DateTime.Now;
var ts2 = endTime - startTime;
startTime = DateTime.Now;
NoGuardSearchGuard(dat, -1);
endTime = DateTime.Now;
var ts3 = endTime - startTime;
txtResult.Text = string.Format("Time Cost: (For) {0} ,(While){1},(Guard) {2}", ts1.TotalMilliseconds, ts2.TotalMilliseconds, ts3.TotalMilliseconds);
}
private int NoGuardSearchFor(int[] dat,int n)
{
int i = dat.Length - 1;
for (; i > 0&& dat[i] != n; i--)
{
}
if (i > 0) return i;
else return 0;
}
private int NoGuardSearchWhile(int[] dat, int n)
{
int i = dat.Length - 1;
while (dat[i] != n && i>0)
{
i--;
}
if (i > 0) return i;
else return 0;
}
private int NoGuardSearchGuard(int[] dat, int n)
{
int i = dat.Length-1;
dat[0] = n;
while (dat[i] != n)
{
i--;
}
return i;
}
结果如下:
时间是毫秒,可以看出加上判断的for和while 的代码时间消耗是几乎相同的,监视哨的效率还是有所体现的,但是没有课本说的那么明显。但是这个技巧还是值得使用,缺点是浪费了一个存贮单元,使用的时候要注意。
maraSun BJFWDQ
ps: 硬件是Lenovo P50。