为什么优先级队列是使用堆实现的,而我们可以更有效地使用向量来实现它
Why priority queue is implemented using heaps when we can implement it using just vector more efficiently
为什么priority_queue
使用堆来实现,而不使用堆,我们也可以只用向量来实现它。
假设我们使用向量作为队列,并将元素按降序排列。 我们可以将其用作优先级队列。
对于插入:我们可以使用二叉搜索。Complexity O(logN)
对于删除:在这里我们也可以使用二进制搜索。Complexity O(logN)
对于顶部元素:O(1)
此外,我们可以在短短O(1)
时间内访问第 k 个最大元素,而堆则不是这种情况。
那么,为什么我们使用堆来实现优先级队列呢?
对于插入:我们可以使用 二叉搜索 .复杂度 O(logN(
对于deltion:在这里我们也可以使用二进制搜索。复杂度 O(logN(
不,你不能。通过使用排序数组/向量,您只能在O(log N)
上搜索正确的索引,但要进行实际的插入或删除,您必须移动其他元素,这是O(N)
。
默认优先级队列确实使用std::vector
。它将堆算法分层,以获得所需的性能特征。
草图实现:
template <typename T>
class priority_queue
{
std::vector<T> elems;
public:
std::vector<T>::const_reference top() const {
return elems.front(); // O(1)
}
void push( const T& value ) {
elems.push_back(value); // Amortized O(1)
std::push_heap(elems.begin(), elems.end()); // O(logN)
}
void pop() {
std::pop_heap(elems.begin(), elems.end()); // O(logN)
elems.pop_back(); // O(1)
}
}
与您的建议进行比较
template <typename T>
class priority_queue
{
std::vector<T> elems;
public:
std::vector<T>::const_reference top() const {
return elems.back(); // O(1)
}
void push( const T& value ) {
std::vector<T>::iterator pos = std::lower_bound(elems.begin(), elems.end(), std::greater<>{}); // O(logN)
elems.insert(pos, value); // O(N)
}
void pop() {
elems.pop_back(); // O(1)
}
}
相关文章:
- 有效地使用std::unordered_map来插入或增加键的值
- 如何有效地在 std::vector 中插入一对?
- 有效地计算多维数组的累积和?
- 如何有效地计算将单位立方体映射到自身的反射和旋转?
- 有效地将大数存储为 2 的幂用于路径问题
- 如何在C++中写入 1000 个文件时有效地缓冲
- 如何有效地找到数组中三元组和的最小差异?
- 如何在C++中有效地将数字值重新分配给字符数组
- C++有效地找到向量中第一个最接近的匹配值?
- 如何有效地操作满足给定谓词的向量中的所有项目?
- 有效地将数据加载到 std::vector 中<char>
- 如何在使用 cin 请求 int 时有效地使用户输入万无一失?
- 如何有效地实现将向量的数据分配给多个变量?
- 为什么优先级队列是使用堆实现的,而我们可以更有效地使用向量来实现它
- 如何有效地实现 std::tuple,使得空类型的元组本身就是空类型
- 如何在C++中有效地实现无穷大和负无穷大支持算术
- 如何用树数据结构有效地实现无序映射
- 有效地实现mpi所有到所有的分散/收集
- 如何有效地实现大量计时器
- 如何有效地实现具有大量大完整子图的图