我想实现具有与数组相关的操作的数据结构 - 即索引和链表 - 快速访问prev / next项。类似于稀疏数组,但内存不是问题 - 关注的是时间复杂性。
要求:
1..N
的整数 - 您可以为它分配一个数组(即内存不是问题)操作:
insert(key, data)
- O(1)find(key)
- O(1) - 返回带有数据的“节点”delete(node)
- O(1)next(node)
- O(1) - 按照键prev(node)
- O(1)我正在考虑在数组中实现指向下一个/上一个占用项目的指针,但我在insert
操作中遇到问题 - 我如何找到上一个和下一个项目,即双重中的位置链接列表放置新项目的位置 - 我不知道如何制作此O(1)
。
如果无法做到这一点,请提供证明。
答案 0 :(得分:8)
您可以使用Van Emde Boas tree。
执行此操作树支持您需要的操作:
Insert: insert a key/value pair with an m-bit key Delete: remove the key/value pair with a given key Lookup: find the value associated with a given key FindNext: find the key/value pair with the smallest key at least a given k FindPrevious: find the key/value pair with the largest key at most a given k
时间复杂度为O(logm),其中m是密钥中的位数。
例如,如果所有键都是0到65535之间的16位整数,则m将为16。
修改
如果密钥在1..N范围内,则每个操作的复杂度为O(loglogN)。
该树还支持最小和最大操作,其复杂度为O(1)。
这棵树的工作原理是使用大量的子树。
例如,假设我们有16位密钥。树的第一层将存储2 ^ 8(= 256)个子树的数组。第一个子项负责0到255之间的键,第二个键负责键256,257,..,511等。
这样可以很容易地查找节点是否存在,因为我们可以直接找到相应的数组元素。
然而,由于我们可能需要搜索256个子树以找到非零元素,因此本身会使查找下一个元素变得困难。
Van Emde Boas树包含两个附加内容,可以轻松找到下一个元素: