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ì)象的屬性來調(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()來進(jìn)行整數(shù)比較。我們使用這個(gè)仿函數(shù)作為std::sort的比較函數(shù),用來對(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ù)可以用來建立大(小)堆
然后實(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)開始與自己的父親比較,如果比父親大(小)就和父親交換位置,直到調(diào)整到根節(jié)點(diǎn)為止
向下調(diào)整算法:從根節(jié)點(diǎn)開始,與左右孩子節(jié)點(diǎn)中較大(較小)者比較,若根節(jié)點(diǎn)比較大(小)則交換位置,一直向下調(diào)整到最后一個(gè)節(jié)點(diǎn)。
接下來就是比較簡(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++使用ImGUI框架開發(fā)一個(gè)簡(jiǎn)單程序
ImGui?是一個(gè)用于C++的用戶界面庫,跨平臺(tái)、無依賴,支持OpenGL、DirectX等多種渲染API,下面就跟隨小編一起學(xué)習(xí)一下如何使用ImGUI框架開發(fā)一個(gè)簡(jiǎn)單程序吧2023-08-08
C++深入講解類與對(duì)象之OOP面向?qū)ο缶幊膛c封裝
學(xué)習(xí)過C語言的小伙伴知道:C語言是面向過程的,關(guān)注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題,接下來讓我們?cè)敿?xì)的了解2022-05-05
c++實(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-05
C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn)
scandir?函數(shù)用于列舉指定目錄下的文件列表,本文主要介紹了C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03

