Vector 带有O(logn)indexOf操作的列表

Vector 带有O(logn)indexOf操作的列表,vector,indexing,data-structures,rust,time-complexity,Vector,Indexing,Data Structures,Rust,Time Complexity,我正在寻找一种数据结构,它可以存储元素列表,同时还支持对给定元素的索引和给定索引的元素进行sub-O(n)查找,以及在索引处插入 元素密集(整数0..n)且唯一,但未排序 例如,在Rust中,此数据结构的使用方式如下: fn main(){ 让mut list=list::new(); 扩展(vec![5,2,0,4,1,3]); assert_eq!(list.get(2),0); 断言(list.get(3),4); assert_eq!(列表索引为(0),2); 断言(第(4)和第(3)项

我正在寻找一种数据结构,它可以存储元素列表,同时还支持对给定元素的索引和给定索引的元素进行sub-
O(n)
查找,以及在索引处插入

元素密集(整数
0..n
)且唯一,但未排序

例如,在Rust中,此数据结构的使用方式如下:

fn main(){
让mut list=list::new();
扩展(vec![5,2,0,4,1,3]);
assert_eq!(list.get(2),0);
断言(list.get(3),4);
assert_eq!(列表索引为(0),2);
断言(第(4)和第(3)项的列表索引);
}

O(√n) 
操作是可以接受的,
O(logn)
是理想的。我在这里画空白;非常感谢任何帮助

单独维护
Vec
HashMap
是否足够?
HashMap
将有一个小于
O(logn)
的值,它是
O(1)~

这样做的缺点似乎是:

  • 您必须将
    Vec
    HashMap
    存储在内存中
  • 删除一个元素后,您还必须减少
    HashMap
    中每个元素的索引,这可能会导致删除成本增加
使用std::collections::HashMap;
结构列表{
索引到值:Vec,
值到索引:HashMap,
}
impl列表{
fn新(索引到值:I)->Self
哪里
I:进入,
{
让index_to_value=index_to_value.into();
让value_to_index=index_to_value
.国际热核实验堆(iter)
.copied()
.enumerate()
.map(|(索引,值)|(值,索引))
.收集();
自我{
索引到值,
值到索引,
}
}
fn获取(&self,n:usize)->选项{
self.index_to_value.get(n).copied()
}
fn索引_of(&self,i:i32)->选项{
self.value_to_index.get(&i).copied()
}
}
fn main(){
let list=list::new(vec![5,2,0,4,1,3]);
断言(list.get(2),Some(0));
断言(list.get(3),Some(4));
assert_eq!(list.index_of(0),Some(2));
assert_eq!(第(4)部分的列表索引,第(3)部分);
}
提供了一个“
IndexedTreestSet
”数据结构,它实现了
O(log n)
中所需的三个操作:

  • 查找索引->元素
  • 查找元素->索引(又称索引)
  • 在索引处插入元素
它使用辅助hashmap将元素映射到树中的节点,然后向上遍历到根。由于树中的每个节点都包含其相对索引,因此可以在根节点上计算绝对索引


我从一种天真的方法(使用
O(n)
inserts)改为这种方法,并将插入的墙执行时间(每秒约100次)从~100ms减少到~1ms。

这是否回答了您的问题@我找到的Stargateur实现了这一点。@Stargateur不,AVL树只根据索引排序,因此它实际上也是一个元素索引列表。因此,按索引进行搜索、插入和删除是O(logn)。聪明的一点是找到一个元素的索引,它使用一个单独的哈希映射。OP是正确的。@Max这是一个很好的问题,你在github上找到的答案非常有趣。请考虑添加一个数据结构描述的答案,如果链接在某个时间点过期。@ StAdvurr我检查了它,并且它看起来是有效的。我自己也不认为这是可能的,但它实际上非常简单和聪明。当然,对于实际较大的n,带有O(logn)操作的AVL树在实践中要比带有O(n)操作的简单列表有效得多。哈希映射根本不支持所需的操作。我真的希望OP能回答这个问题!似乎您还需要在插入时增加HashMap中每个元素的索引?进行插入
O(n)
以及删除。啊,正确,我忽略了“在索引处插入”。出于兴趣,您是否在Rust中实现了这一点,如果是,它是开源的吗?出于兴趣,我想尝试一下,并学习更多关于这个数据结构的知识。@Jason我确实在Rust中实现了它,但不幸的是,我无法将其开源(至今!)