【问题标题】:Getting max and min from BST (C++ vs Java)从 BST 获取最大值和最小值(C++ 与 Java)
【发布时间】:2016-06-04 00:07:38
【问题描述】:

我知道给定一个平衡的二叉搜索树,获取最小和最大元素需要 O(logN),我想分别询问它们在 C++ 和 Java 中的实现。

C++

std::set 为例,调用*set.begin() / *set.rbegin() 可以得到最小值/最大值,并且是常数时间。

Java

HashSet 为例,可以通过调用HashSet.first()HashSet.last() 来获取最小值/最大值,但它是对数时间。

我想知道这是否是因为std::set 做了一些额外的技巧来始终更新beigin()rbegin() 指针,如果是这样,谁能告诉我那个代码?顺便说一句,为什么 Java 没有添加这个技巧,这对我来说似乎很方便......

编辑:

我的问题可能不是很清楚,我想看看 std::set 是如何实现 insert/erase 的,我很想知道 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() 实际上迭代到最后一个元素?

【问题讨论】:

    标签: java c++ data-structures binary-search-tree


    【解决方案1】:

    我的回答与语言无关。 要获取BST 中的MINMAX,您需要始终分别迭代到最左边或最右边的节点。这个操作在O(height),大概是O(log n)

    现在,为了优化这种检索,实现Tree 的类总是可以存储两个指向最左边和最右边节点的额外指针,然后检索它们变成O(1)。当然,这些指针会带来在树中的每个插入操作更新它们的开销。

    【讨论】:

      【解决方案2】:

      begin()rbegin() 仅在恒定时间内返回迭代器。迭代它们不是常数时间。

      没有“begin()/rbegin() 指针”。通过迭代到最左边或最右边的元素来达到最小值和最大值,就像在 Java 中一样,只有 Java 没有显式迭代器。

      【讨论】:

      • 当然,我只对最小值/最大值感兴趣,所以我很好奇这些迭代器在插入/擦除期间是如何更新的,因为它似乎比 Java 的实现更智能..
      • 他们不是。它们只是迭代到最左边或最右边的元素,与 Java 相同。
      • 我检查了 API,它说调用 set.begin()set.rbegin() 都是常数时间,因此我可以通过调用 *set.rbegin() 来获取最大元素,不是吗?对于Java,我认为您也可以使用迭代器获取最小元素,但获取最大元素需要遍历所有元素(线性时间)或调用HashSet.last()(对数时间),这就是为什么我说它对C++更方便。 ..有什么问题吗?
      • 当你说“通过迭代最左边或最右边的元素达到最小值和最大值”时我很困惑,也许我误解了rbegin()?我用一个例子更新了我的问题..
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 2018-04-23
      • 1970-01-01
      相关资源
      最近更新 更多