C++中priority_queue模擬實現(xiàn)的代碼示例
priority_queue概述
priority_queue定義
- 優(yōu)先級隊列是不同于先進先出隊列的另一種隊列。每次從隊列中取出的是具有最高優(yōu)先權(quán)的元素。
priority_queue特點
- 優(yōu)先隊列是一種容器適配器,首先要包含頭文件 #include<queue>, 他和queue不同的就在于我們可以自定義其中數(shù)據(jù)的優(yōu)先級, 讓優(yōu)先級高的排在隊列前面,優(yōu)先出隊。
- 優(yōu)先級隊列默認(rèn)使用vector作為其底層存儲數(shù)據(jù)的容器,在vector上又使用了堆算法將vector中元素構(gòu)造成堆的結(jié)構(gòu),因此priority_queue就是堆,所有需要用到堆的位置,都可以考慮使用priority_queue。
- 注意:默認(rèn)情況下priority_queue是大根堆。如果想讓其生成小根堆,需要使用到仿函數(shù)或者Lambda表達式。
構(gòu)造函數(shù)
由于priority_queue是一種容器適配器,適配的是vector,我們在vector中已經(jīng)寫過它的構(gòu)造函數(shù)了。故priority_queue在此不需要多余的其他構(gòu)造函數(shù)。
// 創(chuàng)造空的優(yōu)先級隊列 priority_queue():m_priority_queue() { } template<class Iterator> priority_queue(Iterator first, Iterator last) : m_priority_queue(first, last) { // 將m_priority_queue中的元素調(diào)整成堆的結(jié)構(gòu) int count = m_priority_queue.size(); int root = ((count - 2) >> 1); for (; root >= 0; root--) AdjustDown(root); }
修改相關(guān)函數(shù)
push
功能:push函數(shù)用來往堆中(尾部)插入一個元素,并向上調(diào)整成新的堆。
//向上調(diào)整 void AdjustUp(int child) { int parent = (child-1)>>1; while (child > 0) { //其中c是一個對象,用該對象去調(diào)用仿函數(shù)來進行比較 if (c(m_priority_queue[parent], m_priority_queue[child])) { std::swap(m_priority_queue[parent], m_priority_queue[child]); child = parent; parent = (child - 1) >> 1; } else { break; } } } void push(const T& val) { m_priority_queue.push_back(val); AdjustUp(m_priority_queue.size()-1); }
pop
功能:pop函數(shù)彈出堆頂元素。具體步驟是:堆頂元素與最后一個數(shù)字進行交換位置。之后在進行尾刪來刪除堆頂。再重新向下調(diào)堆。
//向下調(diào)堆 void AdjustDown(int parent) { int child = (parent << 1) + 1; int size = static_cast<int>(m_priority_queue.size()); while (child< size) { if (child + 1 < size && c(m_priority_queue[child],m_priority_queue[child + 1]) ) { ++child; } if (c(m_priority_queue[parent], m_priority_queue[child])) { std::swap(m_priority_queue[parent], m_priority_queue[child]); parent = child; child = (parent << 1) + 1; } else { break; } } } void pop() { assert(!m_priority_queue.empty()); std::swap(m_priority_queue[0], m_priority_queue[m_priority_queue.size()- 1]); m_priority_queue.pop_back(); AdjustDown(0); }
容量相關(guān)函數(shù)
size
功能:用來獲取堆中的元素個數(shù)。
size_t size() const { return m_priority_queue.size(); }
empty
功能:用來判斷堆中是否為空。
bool empty() const { return m_priority_queue.empty(); }
元素訪問相關(guān)函數(shù)
top
功能:用來獲取堆頂?shù)脑亍?/p>
T& top() { return m_priority_queue.front(); } const T& top() const { return m_priority_queue.front(); }
代碼實現(xiàn)
#pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<vector> #include<assert.h> namespace ZJ { template<class T> class less { public: bool operator() (const T& x, const T& y) const { return x < y; } }; template<class T> class greater { public: bool operator() (const T& x, const T& y) const { return x > y; } }; template<class T,class Container=std::vector<T>, class Compare = ZJ::less<T>> class priority_queue { public: // 創(chuàng)造空的優(yōu)先級隊列 priority_queue():m_priority_queue() { } template<class Iterator> priority_queue(Iterator first, Iterator last) : m_priority_queue(first, last) { // 將m_priority_queue中的元素調(diào)整成堆的結(jié)構(gòu) int count = m_priority_queue.size(); int root = ((count - 2) >> 1); for (; root >= 0; root--) AdjustDown(root); } public: //向上調(diào)整 void AdjustUp(int child) { int parent = (child-1)>>1; while (child > 0) { if (c(m_priority_queue[parent], m_priority_queue[child])) { std::swap(m_priority_queue[parent], m_priority_queue[child]); child = parent; parent = (child - 1) >> 1; } else { break; } } } void push(const T& val) { m_priority_queue.push_back(val); AdjustUp(m_priority_queue.size()-1); } void AdjustDown(int parent) { int child = (parent << 1) + 1; int size = static_cast<int>(m_priority_queue.size()); while (child< size) { if (child + 1 < size && c(m_priority_queue[child],m_priority_queue[child + 1]) ) { ++child; } if (c(m_priority_queue[parent], m_priority_queue[child])) { std::swap(m_priority_queue[parent], m_priority_queue[child]); parent = child; child = (parent << 1) + 1; } else { break; } } } void pop() { assert(!m_priority_queue.empty()); std::swap(m_priority_queue[0], m_priority_queue[m_priority_queue.size()- 1]); m_priority_queue.pop_back(); AdjustDown(0); } size_t size() const { return m_priority_queue.size(); } T& top() { return m_priority_queue.front(); } const T& top() const { return m_priority_queue.front(); } bool empty() const { return m_priority_queue.empty(); } private: Container m_priority_queue; Compare c; }; }
總結(jié)
到此這篇關(guān)于C++中priority_queue模擬實現(xiàn)的文章就介紹到這了,更多相關(guān)C++ priority_queue模擬實現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)算法基礎(chǔ)之循環(huán)隊列示例
這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)算法基礎(chǔ)之循環(huán)隊列,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06StretchBlt函數(shù)和BitBlt函數(shù)用法案例詳解
這篇文章主要介紹了StretchBlt函數(shù)和BitBlt函數(shù)用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08