我知道给定一个平衡的二叉搜索树,得到min和max元素需要O(logN),我想分别询问它们在C ++和Java中的实现。
C ++
以std::set
为例,可以通过调用*set.begin()
/ *set.rbegin()
来获取最小值/最大值,这是常量时间。
爪哇
以HashSet
为例,可以通过调用HashSet.first()
和HashSet.last()
来获取最小值/最大值,但这是对数时间。
我想知道这是否是因为std::set
已经做了一些额外的技巧来总是更新beigin()
和rbegin()
指针,如果是这样,有人能告诉我那些代码吗?顺便说一下为什么Java也没有添加这个技巧,对我来说似乎很方便......
编辑:
我的问题可能不太清楚,我想看看std::set
如何实现插入/擦除,我很想知道begin()
和rbegin()
迭代器是如何更新的操作..
EDIT2:
我现在很困惑。说我有以下代码:
set<int> s;
s.insert(5);
s.insert(3);
s.insert(7);
... // say I inserted a total of n elements.
s.insert(0);
s.insert(9999);
cout<<*s.begin()<<endl; //0
cout<<*s.rbegin()<<endl; //9999
不是*s.begin()
和*s.rbegin()
O(1)操作吗?你是说他们不是吗? s.rbegin()实际上迭代到最后一个元素?
答案 0 :(得分:2)
我的答案不是语言特定的。
要获取int firstDigit = Math.Abs(number);
while(firstDigit >= 10)
firstDigit /= 10;
中的MIN
或MAX
,您需要始终分别迭代到最左侧或最右侧的节点。 BST
中的此操作可能大致为O(height)
。
现在,为了优化此检索,实现O(log n)
的类总是可以存储指向最左侧和最右侧节点的两个额外指针,然后检索它们变为Tree
。当然,这些指针会带来使用树中的每个插入操作更新它们的开销。
答案 1 :(得分:0)
begin()
和rbegin()
仅在常量时间内返回迭代器。迭代它们不是恒定时间。
没有&#39; begin()/rbegin()
指针&#39;。通过迭代到最左边或最右边的元素来达到最小值和最大值,就像在Java中一样,只有Java没有显式迭代器。