3.2.20 #
解答 #
勘误:英文版为 keys() 方法(而非 Size() 方法)。
先来观察一下 keys() 方法的实现:
public IEnumerable<TKey> Keys(TKey lo, TKey hi)
{
var queue = new Queue<TKey>();
Keys(root, queue, lo, hi);
return queue;
}
private void Keys(Node x, Queue<TKey> queue, TKey lo, TKey hi)
{
var cmplo = lo.CompareTo(x.Key);
var cmphi = hi.CompareTo(x.Key);
if (cmplo < 0)
Keys(x.Left, queue, lo, hi);
if (cmplo <= 0 && cmphi >= 0)
queue.Enqueue(x.Key);
if (cmphi > 0)
Keys(x.Right, queue, lo, hi);
}
简单地说,就是从根结点同时向两侧查找,同时把中间的键加入到队列中(树高的倍数+范围内键的数量)。
于是 Keys() 的耗时可以分成两部分:
寻找小于 lo 的最大键值和大于 hi 的最小键值在最坏情况下需要的访问结点数——即树高。
(例如当 lo 小于树中的最小键或者 hi 大于树中最大键时)
以及访问 lo 和 hi 之间所有结点。