C++初阶——优先队列
一、什么是优先队列
优先队列是一个容器适配器,存储于优先队列中的元素按照某种优先级自动排序。优先队列类似于堆,元素可以随时插入,但是只能弹出优先级最高的元素。默认是一个大根堆,也就是元素越大,优先级越高。
二、优先队列的定义及初始化
2.1优先队列的定义
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
priority_queue<int> pq1;//创建一个默认的优先队列
//默认是priority_queue<int,vector<int>,less<int>()> pq1;
priority_queue<int, vector<int>, greater<int>()> pq2;//改为小根堆
return 0;
}
2.2优先队列的初始化
优先队列没法像其他容器一样直接使用初始化列表进行初始化,但它可以使用其它容器的迭代器进行初始化,或者使用push函数与emplace函数依次输入函数。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
priority_queue<int> pq1(v.begin(), v.end());
while (!pq1.empty())
{
cout << pq1.top() << " ";
pq1.pop();
}
return 0;
}
三、list成员函数
3.1empty函数
bool empty() const;
priority_queue提供了一个成员函数empty,用于检查队列是否为空,即检查其大小是否为零。这个函数实际上是调用了底层容器对象的empty成员函数。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
list<int> l = { 1,3,4,5,6,7 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2;
cout << pq1.empty() << endl;
cout << pq2.empty() << endl;
return 0;
}
3.2size函数
size_type size() const;
priority_queue提供了一个成员函数size,用于返回优先队列中元素的数量。这个函数实际上是调用了底层容器对象的size成员函数。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
list<int> l = { 1,3,4,5,6,7 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2;
cout << pq1.size() << endl;
cout << pq2.size() << endl;
return 0;
}
3.3top函数
const_reference top() const;
priority_queue提供了一个成员函数top,用于返回队头即优先级最高的元素。这个函数实际上是调用了底层容器对象的front成员函数。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
list<int> l = { 1,3,4,5,6,7 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2;
cout << pq1.top() << endl;
pq1.pop();
cout << pq1.top() << endl;
return 0;
}
3.4push函数
void push (const value_type& val);
void push (value_type&& val);
priority_queue提供了一个成员函数push,用于向队列中插入一个新的元素。这个新元素的内容会被初始化为val指定的值。push函数首先调用底层容器对象的push_back成员函数来添加元素,然后通过调用heap中的算法调整容器中所有元素的范围,以确保新元素被放置在堆结构中正确的位置。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
list<int> l = { 1,3,4,5,6,7 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2;
pq1.push(10);
cout << pq1.top() << endl;
pq1.pop();
cout << pq1.top() << endl;
return 0;
}
3.5emplace函数
template <class... Args> void emplace (Args&&... args);
priority_queue提供了一个成员函数emplace,它允许你在队列中就地构造一个新元素,这意味着你可以直接传递给新元素构造函数的参数,而不需要先创建一个临时对象再复制或移动到队列中。emplace函数首先调用底层容器的emplace_back成员函数来就地构造元素,然后通过调用push_heap算法调整容器中所有元素的范围,以确保新元素被放置在堆结构中正确的位置。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
list<int> l = { 1,3,4,5,6,7 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2;
pq1.emplace(10);
cout << pq1.top() << endl;
pq1.pop();
cout << pq1.top() << endl;
return 0;
}
3.6pop函数
void pop();
priority_queue提供了一个成员函数pop,用于移除队列顶部的元素,也就是优先级最高的元素。这个操作会减少队列的大小一个单位。在调用pop之前,可以使用top成员函数来检索即将被移除的元素的值。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5,6,7 };
list<int> l = { 1,3,4,5,6,7 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2;
cout << pq1.top() << endl;
pq1.pop();
cout << pq1.top() << endl;
return 0;
}
3.7成员swap函数
void swap (priority_queue& x) noexcept (/*see below*/);
priority_queue提供了一个成员函数swap,它用于交换两个priority_queue容器的元素。这个操作不仅交换了底层容器的内容,还包括它们的比较函数。这个成员函数通过调用底层容器和比较函数的swap非成员函数来实现交换。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5 };
list<int> l = { 5,6,7,8,9 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2(v.begin(), v.end());
priority_queue<int> pq3(pq1);
priority_queue<int> pq4(pq2);
while (!pq1.empty())
{
cout << pq1.top() << " ";
pq1.pop();
}
cout << endl;
while (!pq2.empty())
{
cout << pq2.top() << " ";
pq2.pop();
}
cout << endl;
pq3.swap(pq4);
while (!pq3.empty())
{
cout << pq3.top() << " ";
pq3.pop();
}
cout << endl;
while (!pq4.empty())
{
cout << pq4.top() << " ";
pq4.pop();
}
return 0;
}
四、非成员函数
4.1模板函数swap
template <class T, class Container, class Compare>
void swap (priority_queue<T,Container,Compare>& x, priority_queue<T,Container,Compare>& y) noexcept(noexcept(x.swap(y)));
交换两个优先队列中元素时,可以不适用成员swap函数,转而使用算法标准库中的模板swap函数。
#include <iostream>
#include <vector>
#include <queue>
#include <list>
using namespace std;
int main() {
vector<int> v = { 1,2,3,4,5 };
list<int> l = { 5,6,7,8,9 };
priority_queue<int> pq1(l.begin(), l.end());
priority_queue<int> pq2(v.begin(), v.end());
priority_queue<int> pq3(pq1);
priority_queue<int> pq4(pq2);
while (!pq1.empty())
{
cout << pq1.top() << " ";
pq1.pop();
}
cout << endl;
while (!pq2.empty())
{
cout << pq2.top() << " ";
pq2.pop();
}
cout << endl;
swap(pq3,pq4);
while (!pq3.empty())
{
cout << pq3.top() << " ";
pq3.pop();
}
cout << endl;
while (!pq4.empty())
{
cout << pq4.top() << " ";
pq4.pop();
}
return 0;
}