我认为使用一些保证 O(log n)
性能的二叉搜索树(如AVL、红黑树等)是最好的选择。
利用中序遍历该树来打印当前数据。
O(log n)
呢? - shapiro yaacovhttp://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists
这种方法提供了快速的平均插入时间,但偶尔会出现较长时间。每个其他数字只存储在array [0]中。2的幂输入涉及多个合并步骤,第16个输入最终合并两个8个数字的列表,第1024个输入最终合并两个512个数字的列表。
如前所述,二叉搜索树(偶尔重新平衡)可能是更好的解决方案。
有几个因素会影响您解决方案的效率:
请注意,这些因素更多地基于数据结构而不是算法而变化,因为每次添加元素时都会重新排序,似乎始终是插入排序的变体。
Data Structure | READS | WRITES | Memory | locality | Branches
---------------|--------|--------|------------|----------|---------
Sorted Vector |O(logN) | O(N) | O(N) | high | high (FFTFFT)
Linked List |O(N) | O(1) | O(K*N) | low | low (FFFFFFFFFFT)
Red Black Tree |O(logN) | O(K) | O(K*NlogN) | low | high (FFTFFT)
Btree 16 node |O(logN) | O(16) | O(NlogN) | medium | medium (FFTF)
* K表示与具有相同O()的其他解决方案相比,常数明显更高
最佳解决方案可能因当前架构限制而异。如果内存/缓存大小较小,则排序向量可能是最佳选择。如果分支未命中昂贵,则链表可能是最佳选择,因为除最后一个外的所有分支都将为false。
但似乎如果使用具有大量节点P
的Btree,您将获得向量的局部性和内存效率,具有索引的O(logN)读取速度,并且将将写入数量限制为O(P
)而不是O(N)。 我会从P
开始使用16,然后使用二进制搜索来优化P
,
不幸的是,真正的答案是尝试它们并针对您的用例进行基准测试。
这取决于你如何想要使用结果。
例如:如果你输入了很多数字,并且使用BST来存储它们,你需要超过1000步才能找到索引1000。如果你将排序后的结果存储在一个数组中,你只需要1步(返回index[1000])。
如果你只需要最高或最低的数字,然后将其从列表中删除。之后你需要下一个最高或最低的数字,使用堆会更快。
还要记住,如果随机数字某种程度上是排序的,BST看起来像一个列表,那么插入就不是O(log n)而是O(n)了。
还有很多事情你需要考虑。所以请告诉我们你需要这个东西的目的。