须知
💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力! 👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力! 🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对C++感兴趣的朋友,让我们一起进步!
在算法和数据结构中,优先级队列是一种极其重要的工具,用于按优先级而非插入顺序处理数据。在C++中,std::priority_queue
提供了强大的内置支持,但了解其原理和实现有助于我们更灵活地应用这一数据结构。本文将带你从基础概念出发,逐步实现一个C++版本的优先级队列,并解析其核心原理。
优先级队列是特殊的队列数据结构,其中每个元素都带有一个优先级,队列的处理顺序依据优先级而定,而不是入队顺序。常见特性包括:
在机场登机时,头等舱乘客拥有更高的优先级,会优先登机;在银行排队时,VIP客户的业务会优先处理。优先级队列以数据结构的方式抽象和实现了这些规则。
优先级队列的底层通常基于堆结构(Heap)。堆是一种二叉树,分为最大堆和最小堆:
std::priority_queue
利用堆的机制实现优先级队列。接下来,我们将通过代码逐步构建一个优先级队列。
#include <iostream>
#include <vector>
#include <stdexcept>
class PriorityQueue {
private:
std::vector<int> heap;
void siftUp(int index) {
int parent = (index - 1) / 2;
if (index > 0 && heap[index] > heap[parent]) {
std::swap(heap[index], heap[parent]);
siftUp(parent);
}
}
void siftDown(int index) {
int left = 2 * index + 1;
int right = 2 * index + 2;
int largest = index;
if (left < heap.size() && heap[left] > heap[largest])
largest = left;
if (right < heap.size() && heap[right] > heap[largest])
largest = right;
if (largest != index) {
std::swap(heap[index], heap[largest]);
siftDown(largest);
}
}
public:
void push(int value) {
heap.push_back(value);
siftUp(heap.size() - 1);
}
int pop() {
if (heap.empty()) {
throw std::runtime_error("Priority queue is empty");
}
int top = heap[0];
heap[0] = heap.back();
heap.pop_back();
if (!heap.empty()) {
siftDown(0);
}
return top;
}
bool empty() const {
return heap.empty();
}
int top() const {
if (heap.empty()) {
throw std::runtime_error("Priority queue is empty");
}
return heap[0];
}
};
int main() {
PriorityQueue pq;
pq.push(10);
pq.push(20);
pq.push(5);
std::cout << "Top element: " << pq.top() << std::endl; // 输出 20
std::cout << "Popped element: " << pq.pop() << std::endl; // 输出 20
std::cout << "Popped element: " << pq.pop() << std::endl; // 输出 10
return 0;
}
C++ STL 提供了内置的优先级队列std::priority_queue
,使用起来非常方便。
#include <iostream>
#include <queue>
#include <vector>
int main() {
// 默认是最大堆
std::priority_queue<int> pq;
// 插入元素
pq.push(10);
pq.push(20);
pq.push(5);
// 查看和删除堆顶元素
std::cout << "Top element: " << pq.top() << std::endl; // 输出 20
pq.pop();
std::cout << "Top element after pop: " << pq.top() << std::endl; // 输出 10
// 最小堆的实现
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
minHeap.push(10);
minHeap.push(20);
minHeap.push(5);
std::cout << "Top element of minHeap: " << minHeap.top() << std::endl; // 输出 5
return 0;
}
优先级队列在许多场景中有着广泛的应用:
通过本文的介绍,我们从理论到代码,详细解析了优先级队列的实现与应用。手动实现的优先级队列让我们理解了堆的原理,而C++ STL的std::priority_queue
提供了高度优化的工具,便于快速开发。掌握优先级队列不仅能提高算法效率,也能帮助我们更灵活地解决实际问题。
std::make_heap
、std::push_heap
、std::pop_heap
通过这篇博客,读者将能够深入理解优先级队列的设计思路和实现方法,并学会在实际开发中灵活运用C++的标准工具,提升程序效率和代码质量。
路虽远,行则将至;事虽难,做则必成
下篇文章再会!!!