在优先队列中,元素被赋予优先级,当访问元素时,具有最高优先级的元素最先删除,优先队列具有最高级先出 (first in, largest out)的行为特征。
优先队列支持一系列的基本操作,包括检查队列是否为空、获取队列大小、访问队列头部元素、插入新元素以及移除顶部元素等,其原型定义如下:
priority_queue<Type, Container, Functonal>
: 这个泛型类使用三个模板参数,其中Type
是要存储的数据类型,Container
是底层容器类型,而Functional
则是比较方式的函数或者仿函数对象。
基本数据类型的优先级设置
对于基本数据类型,如int
或float
,优先队列默认使用less
仿函数,生成大顶堆,若需要小顶堆,可以改用greater
仿函数。
对于自定义数据类型,有以下两种方法来设置优先级:
1、重载小于运算符: 在自定义的数据类型中重载<
运算符,如果未改变<
的含义,则默认为大顶堆;如果改变了<
的含义,那么会按照新的定义进行排序。
2、重写仿函数: 自定义一个仿函数类,并重写operator()
来定义比较规则,然后将其作为优先队列的Functional
参数使用。
Q1: 如何在C++中使用STL中的priority_queue存储自定义类型的数据,并根据某个成员变量进行排序?
答: 你可以通过重写仿函数或在自定义类型中重载比较运算符来实现,假设你有一个名为Person
的类,并且你想根据age
成员变量进行排序,你可以这样实现:
class Person { public: int age; string name; Person(string n, int a) : name(n), age(a) {} bool operator<(const Person& p) const { return age < p.age; // 根据年龄从小到大排序 } } // 使用优先队列存储Person对象 priority_queuepq; pq.push(Person("Alice", 30)); pq.push(Person("Bob", 20));
Q2: 如何实现一个每次弹出最小元素的优先队列?
答: 要实现一个每次弹出最小元素的优先队列,你需要使用priority_queue
容器的默认行为,即小顶堆,以下是一个如何使用priority_queue
来实现小顶堆的例子:
#include#include using namespace std; int main() { priority_queue , greater > min_pq; min_pq.push(10); min_pq.push(5); min_pq.push(20); while (!min_pq.empty()) { cout << min_pq.top() << " "; min_pq.pop(); } // 输出: 5 10 20 }
priority_queue
是C++ STL中的一个容器适配器,用于实现优先队列的数据结构。
特性 | 描述 |
头文件 | #include |
基础容器 | 默认情况下,std::vector 是其底层容器,但也可以使用其他序列容器,如std::deque 或std::list |
默认比较器 | 默认情况下,priority_queue 是最大堆,即元素按大于关系排序,可以使用比较函数或函数对象来自定义排序 |
访问元素 | 不支持直接随机访问,元素只能从队头移除 |
容量 | 可以通过empty() 检查队列是否为空,通过size() 获取队列中元素的数量 |
插入元素 | 使用push() 插入元素,元素会被插入到保持堆属性的正确位置 |
删除元素 | 使用pop() 删除队列中的最大元素(对于默认的最大堆) |
访问队头元素 | 使用top() 访问队列中的最大元素而不移除它 |
修改比较器 | 通过在创建时传递比较器,可以创建最小堆或其他自定义优先级队列 |
#include#include #include #include // 为了 std::less 和 std::greater int main() { // 创建一个最大堆 std::priority_queue max_heap; // 创建一个最小堆 std::priority_queue , std::greater > min_heap; // 向最大堆和最小堆中添加元素 for (int i = 1; i <= 10; ++i) { max_heap.push(i); min_heap.push(i); } // 输出最大堆和最小堆的队头元素 std::cout << "Max heap top: " << max_heap.top() << std::endl; // 输出 10 std::cout << "Min heap top: " << min_heap.top() << std::endl; // 输出 1 // 移除最大堆和最小堆的队头元素,直到堆为空 while (!max_heap.empty()) { std::cout << "Max heap pop: " << max_heap.top() << std::endl; max_heap.pop(); } while (!min_heap.empty()) { std::cout << "Min heap pop: " << min_heap.top() << std::endl; min_heap.pop(); } return 0; }
请注意,在创建最小堆时,需要指定一个比较器std::greater<int>
,这将反转比较操作,从而实现最小堆的行为。
谢谢观看!如果您对文章内容有任何问题或意见,也欢迎在下方留言,谢谢!
```