C++ 容器適配器仿函數(shù)與priority_queue的使用
容器適配器
適配器是一種設(shè)計(jì)模式(設(shè)計(jì)模式是一套被反復(fù)使用的、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)),該種模式是將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。 它們的底層都是其他的容器,例如stack和queue的底層容器默認(rèn)是deque,而priority_queue的底層容器是vector。它們是對(duì)這些容器進(jìn)行了包裝提供了用戶想要的接口。
仿函數(shù)
定義:仿函數(shù)不是函數(shù),而是行為類似函數(shù)的類,它重載了opprator()
仿函數(shù)的優(yōu)勢(shì):
- 狀態(tài)維護(hù):仿函數(shù)可以持有狀態(tài),每次調(diào)用可以根據(jù)狀態(tài)改變行為。
- 內(nèi)聯(lián)調(diào)用:由于仿函數(shù)是通過對(duì)象調(diào)用的,編譯器可以輕易地將其內(nèi)聯(lián),減少調(diào)用開銷。
- 高度定制:可以通過對(duì)象的屬性來(lái)調(diào)整其行為。
示例:
#include <iostream> #include <algorithm> #include <vector> class Compare { public: bool operator()(int a, int b) { return a < b; } }; int main() { std::vector<int> numbers = {10, 65, 30, 99, 23}; // 使用仿函數(shù)進(jìn)行排序 std::sort(numbers.begin(), numbers.end(), Compare()); std::cout << "Sorted numbers: "; for (int num : numbers) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在這個(gè)示例中,Compare
是一個(gè)仿函數(shù),它重載了operator()
來(lái)進(jìn)行整數(shù)比較。我們使用這個(gè)仿函數(shù)作為std::sort
的比較函數(shù),用來(lái)對(duì)一個(gè)整數(shù)向量進(jìn)行排序。
priority_queue
priority_queue簡(jiǎn)單介紹
priority_queue是一個(gè)容器適配器(如stack,queue)它的底層容器是vector。它的行為類似與heap(堆)默認(rèn)情況下建立的是大堆。它的底層容器必須能支持隨時(shí)訪問任意位置的元素(這也是為了滿足建堆的要求)
模擬實(shí)現(xiàn)
template<class T> struct less { bool operator()(const T& left, const T& right) { return left < right; } }; template<class T> struct greater { bool operator()(const T& left, const T& right) { return left > right; } };
首先實(shí)現(xiàn)兩個(gè)仿函數(shù)可以用來(lái)建立大(?。┒?/p>
然后實(shí)現(xiàn)向下和向上調(diào)整算法
void AdjustUP(int child) { int parent = ((child - 1) >> 1); while (child) { if (Compare()(c[parent], c[child])) { swap(c[child], c[parent]); child = parent; parent = ((child - 1) >> 1); } else { return; } } } // 向下調(diào)整 void AdjustDown(int parent) { size_t child = parent * 2 + 1; while (child < c.size()) { // 找以parent為根的較大的孩子 if (child + 1 < c.size() && Compare()(c[child], c[child + 1])) child += 1; // 檢測(cè)雙親是否滿足情況 if (Compare()(c[parent], c[child])) { swap(c[child], c[parent]); parent = child; child = parent * 2 + 1; } else return; } }
向上(向下)調(diào)整算法
向上調(diào)整算法:從最后一個(gè)節(jié)點(diǎn)開始與自己的父親比較,如果比父親大(?。┚秃透赣H交換位置,直到調(diào)整到根節(jié)點(diǎn)為止
向下調(diào)整算法:從根節(jié)點(diǎn)開始,與左右孩子節(jié)點(diǎn)中較大(較小)者比較,若根節(jié)點(diǎn)比較大(小)則交換位置,一直向下調(diào)整到最后一個(gè)節(jié)點(diǎn)。
接下來(lái)就是比較簡(jiǎn)單的利用接口進(jìn)行實(shí)現(xiàn)
template<class T, class Container = std::vector<T>, class Compare = less<T>> class priority_queue { public: // 創(chuàng)造空的優(yōu)先級(jí)隊(duì)列 priority_queue() : c() {} template<class Iterator> priority_queue(Iterator first, Iterator last) : c(first, last) { // 將c中的元素調(diào)整成堆的結(jié)構(gòu) int count = c.size(); int root = ((count - 2) >> 1); for (; root >= 0; root--) AdjustDown(root); } void push(const T& data) { c.push_back(data); AdjustUP(c.size() - 1); } void pop() { if (empty()) return; swap(c.front(), c.back()); c.pop_back(); AdjustDown(0); } size_t size()const { return c.size(); } bool empty()const { return c.empty(); } // 堆頂元素不允許修改,因?yàn)椋憾秧斣匦薷目梢詴?huì)破壞堆的特性 const T& top()const { return c.front(); } private: Container c; };
到此這篇關(guān)于C++ 容器適配器仿函數(shù)與priority_queue的文章就介紹到這了,更多相關(guān)C++ 容器適配器與priority_queue內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c語(yǔ)言將字符串中的小寫字母轉(zhuǎn)換成大寫字母
本文主要介紹了c語(yǔ)言將字符串中的小寫字母轉(zhuǎn)換成大寫字母的方法實(shí)例。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04C++使用ImGUI框架開發(fā)一個(gè)簡(jiǎn)單程序
ImGui?是一個(gè)用于C++的用戶界面庫(kù),跨平臺(tái)、無(wú)依賴,支持OpenGL、DirectX等多種渲染API,下面就跟隨小編一起學(xué)習(xí)一下如何使用ImGUI框架開發(fā)一個(gè)簡(jiǎn)單程序吧2023-08-08C++深入講解類與對(duì)象之OOP面向?qū)ο缶幊膛c封裝
學(xué)習(xí)過C語(yǔ)言的小伙伴知道:C語(yǔ)言是面向過程的,關(guān)注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題,接下來(lái)讓我們?cè)敿?xì)的了解2022-05-05c++實(shí)現(xiàn)MD5算法實(shí)現(xiàn)代碼
用c++實(shí)現(xiàn)了md5算法。包含 md5.h 和md5.cpp 兩個(gè)文件。主要參考百度百科 “MD5” 原理,代碼中變量命名也是參考其中的公式,程序的使用說明在md5.h 文件的末尾注釋中2013-11-11基于對(duì)話框程序中讓對(duì)話框捕獲WM_KEYDOWN消息的實(shí)現(xiàn)方法
下面我們將通過程序給大家演示基于對(duì)話框的應(yīng)用程序?qū)M_KEYDOWN消息的捕獲。需要的朋友可以參考下2013-05-05C語(yǔ)言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn)
scandir?函數(shù)用于列舉指定目錄下的文件列表,本文主要介紹了C語(yǔ)言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03