【问题标题】:Most efficient way to sort one element in a vector?对向量中的一个元素进行排序的最有效方法?
【发布时间】:2016-07-07 00:30:48
【问题描述】:

我有一个元素向量,这些元素是根据一些外部值排序的。它是一个大容器,查找排序值相对昂贵。在某些时候,一个元素(仅)需要重新排序。重新排序该元素的最有效方法是什么? std::sort() 向量?擦除插入元素?将元素与其直接邻居进行比较?

编辑:澄清一下,通过擦除插入元素我的意思是这样的:

// erase the key and then insert-sort it
auto iter = std::find(keys.begin(), keys.end(), key);

keys.erase(iter);
SortedInsert(keys, index, <cmp>);

EDIT2:出于其他性能原因,容器需要是向量

【问题讨论】:

  • 您的意思是在现有的排序向量中插入一个值吗?
  • 最坏的情况是 O(n) 复杂度(一个元素从末尾移动到开头)-您可能需要另一种数据结构(可能是std::set?)
  • 关于 sorted vector vs. set 的论点,一篇有趣的文章:asawicki.info/news_1352_the_beauty_of_sorted_arrays.html
  • 既然你问如何快速做到这一点,我假设你会经常这样做以产生影响。在这种情况下,您应该解决这个问题,因为它很慢。例如,您可以拥有额外的未排序向量,当它足够大后,您会将其重新组织到您的排序向量中 - 大成本通过多次插入分摊。

标签: c++ sorting


【解决方案1】:

如果你想在一个有序向量的正确位置直接插入一个元素,你应该使用upper_bound获取一个迭代器并将它传递给insert以将元素放置在正确的位置:

vec.insert(std::upper_bound(vec.begin(), vec.end(), item), item);

请注意,upper_bound 会很快 (O(log n)) 但插入可能会很慢 (O(n)),因为它必须移动插入点之后的所有元素。

但是,在向量的末尾插入并调用 std::sortO(n log n) 所以这是最糟糕的,至少在大向量上!

vec.insert(item);
std::sort(vec.begin(), vec.end());

另一种选择是在向量的末尾插入,然后与前一个元素一起移动,直到它小于或等于。在这种情况下,插入是摊销的O(1),您必须进行O(n) 交换。

恐怕不会有 O(log n) 解决方案,因为您可以使用 list

【讨论】:

    【解决方案2】:

    你可以这样使用:

    std::sort(myvector.begin(), myvector.end)
    

    认为s part of STL and its 实现得很好。

    【讨论】:

    • 不,他的向量已经排序,他只是想把一个值放在正确的位置,所以这不是最有效的
    • 然后二分查找就可以了。
    【解决方案3】:

    考虑将值存储在 MAP 中。

    【讨论】:

      【解决方案4】:

      您可以查看101010的答案。我认为这很有解释性。您可以根据自己的情况进行分析。

      【讨论】:

        猜你喜欢
        • 2018-07-23
        • 1970-01-01
        • 2011-01-19
        • 2014-03-02
        • 1970-01-01
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多