欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++中priority_queue模擬的實現(xiàn)

 更新時間:2024年09月02日 09:32:54   作者:敲上癮  
priority_queue是C++標準庫中的一個容器適配器,用于實現(xiàn)優(yōu)先隊列的數(shù)據(jù)結構,本文主要介紹了c++中priority_queue模擬的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下

一、什么是priority_queue?

priority_queue是C++標準庫中的一個容器適配器,用于實現(xiàn)優(yōu)先隊列(priority queue)的數(shù)據(jù)結構。優(yōu)先隊列是一種特殊的隊列,其中的元素按照一定的優(yōu)先級進行排序,每次取出的元素都是優(yōu)先級最高的。它的優(yōu)先級是可以通過傳入?yún)?shù)自己調整的,它的底層實現(xiàn)通常使用堆(heap)數(shù)據(jù)結構。以下是堆結構的學習鏈接:堆(建堆算法,堆排序)

主要特點

  • 元素有序:隊列中的元素會根據(jù)其優(yōu)先級進行排序,優(yōu)先級最高的元素總是位于隊列的頭部(或稱為隊首)。
  • 操作:主要操作包括插入新元素(push)、刪除優(yōu)先級最高的元素(pop)以及訪問優(yōu)先級最高的元素(top,但不刪除)。
  • 默認行為:默認情況下,priority_queue使用最大堆實現(xiàn),即優(yōu)先級最高的元素(值最大的元素)存儲在根節(jié)點。但可以通過指定比較函數(shù)來改變元素的排序方式,例如使用std::greater可以實現(xiàn)最小堆,即優(yōu)先級最低的元素(值最小的元素)存儲在根節(jié)點。

二、priority_queue如何用?

模板參數(shù)

priority_queue的模板定義通常包含三個參數(shù):

  • typename T:元素類型。
  • typename Container = std::vector<T>:底層容器類型,默認為std::vector<T>。雖然std::deque也滿足條件,但std::vector因其高效的隨機訪問性能而更常被用作底層容器。
  • typename Compare = std::less<T>:比較函數(shù)類型,用于確定元素的優(yōu)先級。默認為std::less<T>,表示元素按從大到小的順序排列;若需按從小到大的順序排列,可指定為std::greater<T>。

以上是priority_queue的接口函數(shù),該篇文章只來學習和模擬c++11以前的接口。

以下是這些接口的使用:

//使用示例
#include<iostream>
#include<queue>
using namespace std;
//這是自定義優(yōu)先級的一種格式
template<typename T>
class gt
{
public:
	//如果返回true則b優(yōu)先,返回false則a優(yōu)先,所以這里使用gt會生成小堆
	bool operator()(T a, T b)
	{
		return a > b;
	}
private:
};
int main()
{
	priority_queue<int> heap1;//int表示儲存的類型
	priority_queue<int, vector<int>> heap2;//這里vector表示使用的底層容器,這里也可以換成deque<int>。
	
	//greater為編譯器提供的類模板,默認的優(yōu)先級是大堆,而使用它可以生成小堆。
	priority_queue<int, vector<int>, greater<int>> heap3;

	//當然也可以自己設計一個優(yōu)先級方式傳入,該方法常常用于儲存自定義類型,而內置類型編譯器提供的就夠用。
	priority_queue<int, vector<int>, gt<int>> heap4;

	//push接口用于存入元素
	heap4.push(2);
	heap4.push(7);
	heap4.push(1);
	heap4.push(5);
	cout << heap4.size() << endl;//size用于計算隊列中元素的個數(shù)
	while (!heap4.empty())//empty用于判斷隊列是否為空
	{
		cout << heap4.top() << ' ';//top獲取隊頭元素
		heap4.pop();//pop刪除隊頭元素
	}
	return 0;
}

以上輸出為:

三、priority_queue模擬實現(xiàn)

1.模板參數(shù)

首先為了區(qū)別于庫里面的優(yōu)先級隊列,我們可以用命名空間限制它的作用域。通過觀察庫里面的priority_queue模板參數(shù)一共有三個,第一個為儲存的元素類型,第二個參數(shù)為需要用的底層容器(默認為vector),第三個參數(shù)為用來調整優(yōu)先級的類模板(需要我們寫一個默認模板),那么我們可以做以下設計:

#include<iostream>
#include<vector>
using namespace std;
namespace byte//用命名空間限制它的作用域,來區(qū)別于庫里面的優(yōu)先級隊列
{
	template<typename T, class Container = vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		//...
	private:
		//...
	};
}

 注意:這里vector模板我們可以使用庫里面的,但優(yōu)先級隊列模板(less<T>)需要我們自己寫。

2.成員變量

STL的任何模擬,如果在考慮成員變量如何設計而發(fā)愁,我們可以去想如何儲存對象的數(shù)據(jù)進而來設計我們的成員變量。這里我們用的是容器Container(即vector<int>)來儲存數(shù)據(jù)的,所以我們的成員變量之一類型一定是Container,其次因為想到不同對象傳入的Compare可能不同,具有特殊性,所以我們也可以把Compare(優(yōu)先級調整的類模板)作為成員變量。如下:

private:
	Container arr;
	Compare comp;

3.成員函數(shù)

因為在priority_queue模擬中并不涉及到動態(tài)內存開辟和一些特殊理,所以這里的構造函數(shù)用編譯器默認提供的構造函數(shù)就夠用了,并不需要我們自己編寫。

在優(yōu)先級隊列中因為涉及到堆的調整所以在push和pop接口的設計中有些復雜,其他接口的設計都非常簡單就不在講解,后面大家直接看源碼。

3.1.push

首先需要把arr看做是一個堆結構,無論arr里面有沒有元素,然后直接把元素push_back到arr中,此時該元素所在位置為堆底,而且并不一定是正確的位置,接下來要做的就是對該元素進行向上調整。

父子節(jié)點的定義:子節(jié)點記為child,父節(jié)點記為father。

child=arr.size()-1

father=(child-1)/2(理解原理后可以當做公式記憶,可通過一下鏈接參考學習)

向下調整的方法我在以下文章中有具體講解:

堆(建堆算法,堆排序)_初始建堆算法

3.2.pop

該函數(shù)主要功能是pop堆頂元素,但是如果直接pop堆頂元素(下標為0)的話,那么下標為1的會成為堆頂元素,會使原來的父子關系和兄弟關系混亂,要重新調整起來極其復雜,所一需要換一種方案,我們可以把堆頂元素與堆底元素交換然后pop堆底元素,然后對堆進行向下調整。

父子節(jié)點的定義:子節(jié)點記為child,父節(jié)點記為father。

father=0

child=father*2+1(這里father和child的計算公式是可以互推的)

向下調整的方法我在以下文章中有具體講解:

堆(建堆算法,堆排序)_初始建堆算法

四、源碼

#include<iostream>
#include<vector>
using namespace std;
namespace byte
{
	template<typename T>
	class less
	{
	public:
		//如果返回true則b優(yōu)先,返回false則a優(yōu)先,所以這里使用gt會生成小堆
		bool operator()(T a, T b)
		{
			return a < b;
		}
	private:
	};
	template<typename T>
	class greater
	{
	public:
		//如果返回true則b優(yōu)先,返回false則a優(yōu)先,所以這里使用gt會生成小堆
		bool operator()(T a, T b)
		{
			return a > b;
		}
	private:
	};

	template<typename T, class Container = vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:

		void AdjustUP()
		{
			int child = arr.size() - 1, father = (child - 1) / 2;
			while (child > 0)
			{
				if (comp(arr[father], arr[child]))
				{
					std::swap(arr[child], arr[father]);
					child = father;
					father = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		void AdjustDOWN()
		{
			int father = 0, child = father * 2 + 1;
			while (child < arr.size())
			{
				if (child + 1 < arr.size() && comp(arr[child], arr[child + 1]))
				{
					child++;
				}
				if (comp(arr[father], arr[child]))
				{
					std::swap(arr[child], arr[father]);
					father = child;
					child = father * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}
		void push(T x)
		{
			arr.push_back(x);
			AdjustUP();
		}
		void pop()
		{
			std::swap(arr[0], arr[arr.size() - 1]);
			arr.pop_back();
			AdjustDOWN();
		}
		T top()
		{
			return arr[0];
		}
		size_t size()
		{
			return arr.size();
		}
		bool empty()
		{
			return arr.size() == 0;
		}
	private:
		Container arr;
		Compare comp;
	};
}

到此這篇關于c++中priority_queue模擬的實現(xiàn)的文章就介紹到這了,更多相關c++ priority_queue模擬內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • C語言strlen函數(shù)實現(xiàn)讀取字符串長度詳解

    C語言strlen函數(shù)實現(xiàn)讀取字符串長度詳解

    這篇文章主要介紹了用C語言的strlen函數(shù)來實現(xiàn)讀取字符串長度的過程,strlen所作的是一個計數(shù)器的工作,它從內存的某個位置開始掃描,直到碰到第一個字符串結束符'\0'為止
    2022-04-04
  • C語言實現(xiàn)學生檔案管理系統(tǒng)

    C語言實現(xiàn)學生檔案管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)學生檔案管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++ 實現(xiàn)帶監(jiān)視哨的順序查找算法

    C++ 實現(xiàn)帶監(jiān)視哨的順序查找算法

    這篇文章主要介紹了C++ 實現(xiàn)帶監(jiān)視哨的順序查找算法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • C++實現(xiàn)二分法求連續(xù)一元函數(shù)根

    C++實現(xiàn)二分法求連續(xù)一元函數(shù)根

    這篇文章主要為大家詳細介紹了C++實現(xiàn)二分法求連續(xù)一元函數(shù)根,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C++關于類結構體大小和構造順序,析構順序的測試詳解

    C++關于類結構體大小和構造順序,析構順序的測試詳解

    這篇文章主要介紹了C++類結構體大小和構造順序,析構順序的測試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • C++中的extern “C”用法詳解

    C++中的extern “C”用法詳解

    這篇文章主要介紹了C++中的extern “C”用法詳解,簡單來說,extern “C”是C++聲明或定義C語言符號的方法,是為了與C兼容,需要的朋友可以參考下
    2015-03-03
  • 一文帶你掌握C++中的繼承

    一文帶你掌握C++中的繼承

    繼承機制是面向對象程序設計使代碼可以復用的最重要的手段,它允許程序員在保持原有類特性的基礎上進行擴展,增加功能,本文詳解介紹了C++中的繼承,感興趣的同學可以借鑒一下
    2023-05-05
  • C語言數(shù)組與地址、數(shù)組名到底是什么詳解

    C語言數(shù)組與地址、數(shù)組名到底是什么詳解

    在寫代碼的時候,我們經(jīng)常用到數(shù)組,那么有沒有想過數(shù)組名是什么呢?這篇文章主要給大家介紹了關于C語言數(shù)組與地址、數(shù)組名到底是什么的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • C++中typeid實現(xiàn)原理詳解

    C++中typeid實現(xiàn)原理詳解

    這篇文章主要給大家介紹了關于C++中typeid實現(xiàn)原理的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • C語言中getchar()函數(shù)的用法小結

    C語言中getchar()函數(shù)的用法小結

    這篇文章主要介紹了C語言中getchar()函數(shù)的用法,getchar是輸入函數(shù),輸入的過程是什么呢,本文給大家詳細講解,對C語言getchar()函數(shù)相關知識感興趣的朋友一起看看吧
    2022-10-10

最新評論