C++中priority_queue的使用與模擬實現(xiàn)
priority_queue的使用
priority_queue簡介
- 優(yōu)先隊列是一種容器適配器,有嚴格的排序標準,它的第一個元素總是它所包含的元素中最大的(或最小的)。
- 此上下文類似于堆,在堆中可以隨時插入元素,并且只能檢索最大堆(或 最小堆)元素(優(yōu)先隊列中位于頂部的元素)。
- 默認情況下,如果沒有為特定的priority_queue類實例化指定容器類,則使用vector。
priority_queue的使用
| 成員函數(shù) | 功能 |
|---|---|
| push | 插入數(shù)據(jù) |
| pop | 刪除優(yōu)先級隊列中最大(最小)元素,即堆頂元素 |
| top | 返回優(yōu)先級隊列中最大(最小)元素,即堆頂元素 |
| empty | 檢測優(yōu)先級隊列是否為空 |
| size | 獲取隊列中有效元素個數(shù) |
void TestPriorityQueue()
{
// 默認情況下,創(chuàng)建的是大堆,其底層按照小于號比較
vector<int> v{ 3, 2, 7, 6, 0, 4, 1, 9, 8, 5 };
priority_queue<int> q1;// 構(gòu)建優(yōu)先級隊列
for (auto e : v)
q1.push(e);//尾插
cout << "q1中元素個數(shù):" << q1.size() << endl;
for (size_t i = 0;i<v.size();++i)
{
cout << q1.top() << " ";//輸出棧頂?shù)臄?shù)據(jù)
q1.pop();//尾刪
}
cout << endl;
cout << "q1中元素個數(shù):" << q1.size() << endl;
cout << endl;
// 如果要創(chuàng)建小堆,將第三個模板參數(shù)換成greater比較方式
priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());
for (size_t i = 0; i<v.size(); ++i)
{
cout << q2.top() << " ";//輸出棧頂?shù)臄?shù)據(jù)
q2.pop();//尾刪
}
cout << endl;
}

如果在priority_queue中放自定義類型的數(shù)據(jù),用戶需要在自定義類型中提供> 或者< 的重載。
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
bool operator<(const Date& d)const
{
return (_year < d._year) ||
(_year == d._year && _month < d._month) ||
(_year == d._year && _month == d._month && _day < d._day);
}
bool operator>(const Date& d)const
{
return (_year > d._year) ||
(_year == d._year && _month > d._month) ||
(_year == d._year && _month == d._month && _day > d._day);
}
friend ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
private:
int _year;
int _month;
int _day;
};
void TestPriorityQueue()
{
// 大堆,需要用戶在自定義類型中提供<的重載
priority_queue<Date> q1;
q1.push(Date(2022, 1, 7));
q1.push(Date(2022, 1, 1));
q1.push(Date(2022, 1, 31));
cout << q1.top() << endl;
cout << endl;
// 如果要創(chuàng)建小堆,需要用戶提供>的重載
priority_queue<Date, vector<Date>, greater<Date>> q2;
q2.push(Date(2022, 1, 7));
q2.push(Date(2022, 1, 1));
q2.push(Date(2022, 1, 31));
cout << q2.top() << endl;
}

priority_queue的模擬實現(xiàn)
priority_queue的底層實際上就是堆結(jié)構(gòu),可以參考博主之前寫的有關(guān)堆的文章數(shù)據(jù)結(jié)構(gòu)之堆
namespace nzb
{
//比較方式(使內(nèi)部結(jié)構(gòu)為大堆)
template<class T>
class Less
{
public:
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
//比較方式(使內(nèi)部結(jié)構(gòu)為小堆)
template<class T>
class Greater
{
public:
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
template<class T, class Container = vector<T>, class Compare = Less<T>>
class priority_queue
{
public:
priority_queue()
{}
template<class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
//將迭代器中的數(shù)據(jù)插入優(yōu)先級隊列中
while (first != last)
{
_con.push_back(*first);
first++;
}
//從最后一個非葉子結(jié)點向上調(diào)整
for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(i);
}
}
//堆的向上調(diào)整
void AdjustUp(size_t child)
{
size_t parent = (child - 1) / 2;//找到父節(jié)點
while (child > 0)
{
if (_com(_con[parent], _con[child]))//判斷是否需要交換
{
//交換父子結(jié)點
swap(_con[parent], _con[child]);
//繼續(xù)向上調(diào)整
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
//向下調(diào)整
void AdjustDown(size_t parent)
{
size_t child = parent * 2 + 1;//算出左子節(jié)點的下標
while (child < _con.size())
{
//找出子結(jié)點中符合比較方式的值
if (child + 1 < _con.size() && _com(_con[child], _con[child + 1]))
{
child++;
}
//通過所給比較方式確定是否需要交換結(jié)點位置
if (_com(_con[parent], _con[child]))
{
//交換父子結(jié)點
swap(_con[parent], _con[child]);
//繼續(xù)向下調(diào)整
parent = child ;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//插入數(shù)據(jù)
void push(const T& x)
{
_con.push_back(x);
AdjustUp(_con.size() - 1);//將最后一個元素向上調(diào)整
}
//刪除數(shù)據(jù)
void pop()
{
swap(_con[0], _con[_con.size() - 1]);//交換首尾數(shù)據(jù)
_con.pop_back();//尾刪
AdjustDown(0);//首元素向下調(diào)整
}
//訪問頭元素
const T& top() const
{
return _con[0];
}
//獲取隊列中有效元素個數(shù)
size_t size()
{
return _con.size();
}
//判空
bool empty()
{
return _con.empty();
}
private:
Container _con;//底層容器
Compare _com;//比較方式
};
}
到此這篇關(guān)于C++中priority_queue的使用與模擬實現(xiàn)的文章就介紹到這了,更多相關(guān)C++ priority_queue內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用C語言舉例講解數(shù)據(jù)結(jié)構(gòu)中的算法復(fù)雜度結(jié)與順序表
這篇文章主要介紹了講解數(shù)據(jù)結(jié)構(gòu)中的算法復(fù)雜度結(jié)與順序表的C語言版示例,包括對時間復(fù)雜度和空間復(fù)雜度等概念的簡單講解,需要的朋友可以參考下2016-02-02
C語言實現(xiàn)銷售管理系統(tǒng)設(shè)計
這篇文章主要為大家詳細介紹了C語言實現(xiàn)銷售管理系統(tǒng)設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03

