对已排序容器中的一个元素进行排序
Sorting one element in a sorted container
我有一个排序对象的向量。在某些时候,其中一个对象被更新,并且该元素(仅)必须再次排序。
最好的方法是什么?std::sort()在整个容器上(如果容器已经排序,它更快吗?)或擦除()对象并将其插入()它应该在的位置?
编辑:在这种情况下,我必须使用矢量容器
理论上,你应该使用 std::lower_bound
和 std::insert
的组合,如下例所示:
#include <iostream>
#include <vector>
#include <algorithm>
template<typename T>
void insert(T value, std::vector<T>& data) {
auto it = std::lower_bound(data.begin(), data.end(), value);
data.insert(it, value);
}
template<typename C>
void show(const C& data) {
for(const auto & item : data) {
std::cout << item << " ";
}
std::cout << "n";
}
int main() {
std::vector<int> data { 1, 2, 4, 5, 7, 9 };
show(data);
insert(3, data);
show(data);
insert(6, data);
show(data);
}
输出:
$ g++ example.cpp -std=c++14
./a.out
1 2 4 5 7 9
1 2 3 4 5 7 9
1 2 3 4 5 6 7 9
std::lower_bound(beg, end, val)
会发现迭代器指向范围[beg, end)
中的第一个元素,该元素不小于(即大于或等于)值(参见 cpp首选项);它仅适用于排序的容器。它的复杂性在std::distance(beg, end)
中是对数的。
std::vector<T>::insert(it, value)
将在it
之前插入value
。
在实践中(对于相对较少的元素),最好使用线性搜索直到插入点,然后std::insert
。换句话说:线性搜索是O(N)
的,std::lower_bound
是O(log N)
的,但是对于具有大约 10-50 个元素的向量,线性搜索更快(由于缓存效应)(您的里程可能会有所不同)。
-
std::sort
具有O(n log n)
的复杂性。 - 移除和插入具有
O(n)
的复杂性。 - 旋转具有
O(log n) + O(length_of_rotation)
的复杂性。
您可以使用std::lower_bound
查找新地点,std::rotate
固定顺序:
void update(std::vector<int>& v, std::vector<int>::iterator old_it, int new_value)
{
if (old_it == v.end()) {
return;
}
auto it = std::lower_bound(v.begin(), v.end(), new_value);
*old_it = new_value;
if (old_it < it) {
std::rotate(old_it, old_it + 1, it);
} else if (it < old_it) {
std::rotate(it, old_it, old_it + 1);
}
}
演示
std::rotate
与remove
/insertion
的优势在于复制/移动的数量:如果您只需要交换前 2 个元素,std::rotate
只执行交换,而删除 shift 所有元素,并在另一侧再次插入 shift 元素。
如果向量已经排序,您可以通过二分法轻松找到更新值的新位置(与 size+2 的值进行比较并迭代......然后你在旧地方和新地方之间移动所有元素。
这是一种相当优化的方式,因为新旧地方之间的转换是一个结合std::erase
和std::insert
的浓缩操作,但编写和测试会更乏味......
- 根据另一个矢量对一个矢量进行排序
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 给定一个枢轴点,按照它们与枢轴点构成的角度递增顺序对一组点进行排序
- 为什么这个选择排序算法仍然切换一个元素,当它已经是其他元素中最小的元素时?
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 通过将其中一个模板更改为 muliset 后,我可以在 PBDS 排序集上使用计数功能<int>less_equal<int>
- 只对向量中的一个类成员进行排序,其他成员保持不变
- 为什么这个快速排序实现给出了一个奇怪的输出
- 使用迭代器进行合并排序中的一个缓冲区
- 使用C++对一个巨大文件中的文本行进行字典式外部排序
- 我想要一个改变数组快速排序的2个数字的函数
- 如何在一个巨大的文本文件中对整数进行排序
- 如何创建一个C++程序来读取字符串数组中的信息,然后将其排序到类中?
- C++一个具有 2 个参数(___ _____,整数长度)的函数中的快速排序
- 按另一个向量对一个向量进行排序
- 我正在编写一个拆分为 3 的合并排序,我不知道为什么它不起作用
- 我写了一个快速的排序代码,逻辑似乎很正确,但是控制台上没有输出
- 尝试自定义一个函数来对不同种类元素的向量进行排序
- 冒泡排序一个结构数组
- 我如何在c++中排序一个整数字符串