类似 STL 的 Java 红黑树/TreeSet/Map 和带有非快速失败/安全迭代器的链表

发布于 2024-10-15 21:58:39 字数 546 浏览 3 评论 0原文

我正在寻找一个具有红黑树和链接列表实现的库,提供不快速失败的迭代器。我希望拥有与使用 STL 在 C++ 中所做的相同的功能,即:

  • 在树/列表中插入不会使任何迭代器无效
  • 删除只会使指向被删除元素的迭代器
  • 无效可以以某种方式存储“迭代器的“位置”并引用它指向的值。

这个实现会很好,因为它提供了在使用列表/树的一部分时修改列表/树的能力。以下是一些示例:

  • 将链表/红黑树中的相邻元素获取到 O(1) 中的某个存储值
  • 批量插入/删除(没有限制,例如每个位置增量删除一个)
  • 通过位置在 O(1) 中拆分链表 当存储了迭代器的位置时,迭代器的
  • 更有效的删除(例如,通过将迭代器保持在链表中的某个位置,删除是 O(1),而不是 O(N))

我还希望该库/源代码/实现拥有一些 Apache/GPL 友好的许可证并且具有相当的可扩展性(因此我可以进行自己的修改来实现一些操作,例如上面示例中的操作)。

如果不存在这样的库,是否有其他库可以帮助我自己实现这两个数据结构?

I am looking for a library with a Red-black tree and Linked list implementation offering iterators which are not fail-fast. I would like to have the same functionality as I do in C++ using STL and that is:

  • insertion in the tree/list does not invalidate any iterators
  • removal invalidates only the iterator that points at the element being removed
  • it is possible to somehow store the "position" of the iterator and refer to the value it is pointing at

This implementation would be nice as it would offer the ability to modify the list/tree while using the a part of it. Here are some examples:

  • obtaining adjacent element in linked list / red-black tree to some stored value in O(1)
  • batch insertions / removals (no constraints such as one removal per position increment)
  • splitting linked list in O(1) via position of the iterator
  • more efficient removals when having stored position of the iterator (e.g. by keeping iterators to a position in linked list, removal is O(1), not O(N))

I would also like that library/source code/implementation to have some Apache/GPL-friendly licence and is fairly extensible (so I can make my own modifications to implement some operations such as the ones from the examples above).

If there exists no such library, is there some other library which could help me in implementing those two data structures on my own?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

﹎☆浅夏丿初晴 2024-10-22 21:58:39

这些都很容易自己实现。迭代器必须做三件事:

  1. 存储两个引用,一个到“当前”元素,一个到外部容器对象(存储根引用(树)或头的 blob) /tail 引用(列表))。

  2. 能够确定引用的元素是否有效(简单,如果父指针为空(树)或上一个/下一个指针为空(列表),那么这最好是树根或头/尾)列表)。当对无效迭代器尝试任何操作时抛出一些东西。

  3. 能够找到上一个/下一个元素。

有几个问题:对于列表,高效支持 java.util.ListIterator 的 nextIndex() 和 prevIndex() 会很痛苦,当然,现在您还面临处理并发修改的问题!下面是一个事情可能会变得糟糕的例子:

while (it.hasNext()) {
    potentially_delete_the_last_element()
    it.next() // oops, may throw NoSuchElementException.
}

避免这种情况的方法是永远不要在检查列表是否有下一个/上一个和实际检索下一个/上一个之间修改列表。

These are both pretty easy to implement yourself. The iterator has to do three things:

  1. Only store two references, one to the "current" element and one to the outer container object (the blob storing the root reference (tree) or the head/tail references (list)).

  2. Be able to determine whether the referred-to element is valid (easy, if parent pointer is null (tree) or prev/next pointers are null (list) then this better be the tree root or the head/tail of the list). Throw something when any operations at all are attempted on an invalid iterator.

  3. Be able to find the prev/next element.

There are a couple gotchas: for the list, it would be a pain to support the java.util.ListIterator's nextIndex() and prevIndex() efficiently, and, of course, now you have the problem of dealing with concurrent modifications! Here's an example of how things could go bad:

while (it.hasNext()) {
    potentially_delete_the_last_element()
    it.next() // oops, may throw NoSuchElementException.
}

The way to avoid this would be never to modify the list between checking if it has next/prev and actually retrieving next/prev.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文