国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++雜貨鋪】優(yōu)先級隊列的使用指南與模擬實現(xiàn)

這篇具有很好參考價值的文章主要介紹了【C++雜貨鋪】優(yōu)先級隊列的使用指南與模擬實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【C++雜貨鋪】優(yōu)先級隊列的使用指南與模擬實現(xiàn),C++雜貨鋪,c++,開發(fā)語言,優(yōu)先級隊列,堆,熱門

一、priority_queue的介紹

  • 優(yōu)先級隊列是一種容器適配器,根據(jù)嚴格的弱排序標準,它的第一個元素總是它所包含的元素中最大的。

  • 此上下文類似于堆,在堆中可以隨時插入元素,并且只能檢索最大堆元素(優(yōu)先級隊列中位于頂部的元素)。

  • 優(yōu)先級隊列被實現(xiàn)為容器適配器,容器適配器即將特定容器類封裝作為其底層容器類,queue 提供一組特定的成員函數(shù)來訪問其元素。元素從特定容器的“尾部”彈出,其稱為優(yōu)先級隊列的頂部。

  • 底層容器可以是任何標準容器類模板,也可以是其他特定設(shè)計的容器類。容器應(yīng)該可以通過隨機訪問、迭代器訪問,并支持以下操作:

    • empty():檢測容器是否為空

    • size():返回容器中有效元素的個數(shù)

    • front():返回容器中第一個元素的引用

    • push_back():在容器尾部插入元素

    • pop_back():刪除容器尾部元素

  • 標準容器類 vector 和 deque 滿足這些需求。默認情況下,如果沒有為特定的 priority_queue 類實例化指定容器類,則使用 vector。

  • 需要支持隨機訪問迭代器,以便始終在內(nèi)部保持堆結(jié)構(gòu)。容器適配器通過在需要時自動調(diào)用算法函數(shù) make_heap、push_heap 和 pop_heap 來自動完成次操作。

二、priority_queue的使用

優(yōu)先級隊列默認使用 vector 作為其底層存儲數(shù)據(jù)的容器,在 vector 上又使用了堆算法將 vector 中元素構(gòu)造成堆的結(jié)構(gòu),因此 priority_queue 就是堆,所有需要用到堆的位置,都可以考慮使用 priority_queue。注意:默認情況下 priority_queue 是大堆。

函數(shù)聲明 接口說明
priority_queue() 構(gòu)造一個空的優(yōu)先級隊列
empty() 檢測優(yōu)先級隊列是否為空,是返回 true,否則返回 false
top() 返回優(yōu)先級隊列中最大(最?。┰兀炊秧斣?/td>
push(x) 在優(yōu)先級隊列中插入元素 x
pop() 刪除優(yōu)先級隊列中最大(最下)元素,即堆頂元素

小Tips:默認情況下,priority_queue 是大堆(默認第三個模板參數(shù)是 less);如果在 priority_queue 中放自定義類型的數(shù)據(jù),用戶需要在自定義類型中提供 > 或者 < 的重載。

2.1 數(shù)組中的第k個最大元素

【C++雜貨鋪】優(yōu)先級隊列的使用指南與模擬實現(xiàn),C++雜貨鋪,c++,開發(fā)語言,優(yōu)先級隊列,堆,熱門

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) 
    {
        //建一個大堆,向下調(diào)整建堆的時間復(fù)雜度是O(N)
        priority_queue<int> pq(nums.begin(), nums.end());

        //pop k-1次,時間復(fù)雜度是O(K*logN)
        while(--k)
        {
            pq.pop();
        }

        return pq.top();
    }
};

上面這種做法當(dāng) K 的值接近 N 的時候,它的時間復(fù)雜度就是 O(N*logN),是不滿足題目要求的,下面再用另外一種方法來解決。

lass Solution {
public:
    int findKthLargest(vector<int>& nums, int k) 
    {
        //用前k個數(shù)建一個小堆
        priority_queue<int, vector<int>, greater<int>> pq(nums.begin(), nums.begin() + k);

        //遍歷剩下的 N-k 個,比堆頂大就換進去
        //時間復(fù)雜度是 (N-K)logN
        for(size_t i = k; i < nums.size(); i++)
        {
            if(nums[i] > pq.top())
            {
                pq.pop();
                pq.push(nums[i]);
            }
        }
        return pq.top();
    }
};

上面這種解法是先用數(shù)組中的前 K 個元素建一個小堆,然后從數(shù)組的第 K+1 個元素開始往后遍歷,遇到比堆頂元素大的就將堆頂?shù)脑?pop 出來,將當(dāng)前元素 push 進去。建堆的時間復(fù)雜度是 O(K),更新小堆的時間復(fù)雜度是 O((N-K)logK),這種做法當(dāng) K 很小的時候時間復(fù)雜度可以近似看做 O(NlogK),當(dāng) K 很大的時候,時間復(fù)雜度可以近似看做 O(logK)。

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

3.1 仿函數(shù)

仿函數(shù)本質(zhì)上一個類,之所以把它叫仿函數(shù)是因為這個類的對象可以像函數(shù)一樣去使用。舉例如下:

//一個仿函數(shù)
template<class T>
class Less
{
public:
	bool operator()(const T& x, const T& y)
	{
		return x < y;
	}
};


int main()
{
	Less<int> lessfunc;//定義一個對象
	cout << lessfunc(1, 2) << endl;//該類型對象可以像函數(shù)一樣去使用
	//cout << lessfunc.operator()(1, 2) << endl;//和上面等價
	return 0;
}

小Tips:仿函數(shù)一般都是類模板,這樣就可以支持不同類型的大小比較,前提是該種類型重載實現(xiàn)了比較運算符。仿函數(shù)的誕生是為了代替函數(shù)指針,函數(shù)指針的可讀性比較差。

3.2 成員變量

template<class T, class Container=std::vector<T>, class Compare = Less<T>>
	class priority_queue
	{
	public:
		//成員
	private:
		Container _con;
	};

小Tips:需要注意這里有三個模板參數(shù),第一個模板參數(shù)表示要在優(yōu)先級隊列中存儲的數(shù)據(jù)類型;優(yōu)先級隊列本質(zhì)上也是一個容器適配器,所以第二個模板參數(shù)表示優(yōu)先級隊列要使用的底層容器;第三個模板參數(shù)是一個仿函數(shù),用來進行大小比較的,因為優(yōu)先級隊列中會涉及到建大堆還是建小堆,中間會涉及到比較,如果沒有這個仿函數(shù),那么大小比較就只能寫死了,這樣不太好。

3.3 成員函數(shù)

3.3.1 構(gòu)造函數(shù)

priority_queue()
{}

template<class InputeIterator>
priority_queue(InputeIterator first, InputeIterator last)
{
	//先將數(shù)據(jù)插入
	while (first != last)
	{
		_con.push_back(*first);
		++first;
	}

	//建堆,從最后一個非葉子節(jié)點開始向下調(diào)整
	for (int i = (_con.size() - 1) / 2; i >= 0; i--)
	{
		AdjustDown(i);
	}
}

小Tips:迭代器區(qū)間構(gòu)造函數(shù)是一個函數(shù)模板,只要是能支持 ++ 操作的迭代器區(qū)間都可以,即單向迭代器、雙向迭代器、隨機迭代都可以。其次將數(shù)據(jù)插入容器后還需要建堆,這里采用向下調(diào)整建堆,它的時間復(fù)雜度是 O(N)。

3.3.2 AdjustDown

void AdjustDown(int parent)
{
	Compare com;
	while (parent * 2 + 1 < (int)_con.size())
	{
		//找到最大的孩子
		int maxchild = parent * 2 + 1;
		if (maxchild + 1 < (int)_con.size() && com(_con[maxchild], _con[maxchild + 1]))
		{
			maxchild++;
		}

		//和父節(jié)點比較
		if (com(_con[parent], _con[maxchild]))
		{
			std::swap(_con[maxchild], _con[parent]);
			parent = maxchild;
		}
		else
		{
			break;
		}
	}
}

小Tips:在仿函數(shù)的加持下,向下調(diào)整代碼中的大小比較不再固定,建大堆和小堆這一份代碼就夠了,最終是大堆還是小堆是由仿函數(shù)來控制的。

3.3.3 push

void push(const T& val)
{
	_con.push_back(val);
	AdjustUp(_con.size() - 1);
}

小Tips:在優(yōu)先級隊列的尾部追加數(shù)據(jù),會涉及到向上調(diào)整,向上調(diào)整的代碼如下所示。

3.3.4 AdjustUp

void AdjustUp(int child)
{
	Compare com;
	int parent = (child - 1) / 2;
	while (child > 0)//父親不會小于0,因此這里的判斷條件要用孩子大于0,孩子等于0說明已經(jīng)調(diào)整到根節(jié)點,就無需繼續(xù)調(diào)整了
	{
		if (com(_con[parent], _con[child]))
		{
			std::swap(_con[child], _con[parent]);
			child = parent;
			parent = (child - 1) / 2;//這里parent不會小于0
		}
		else
		{
			break;
		}
	}
}

3.3.5 pop

void pop()
{
	std::swap(_con[0], _con[_con.size() - 1]);
	_con.pop_back();
	AdjustDown(0);
}

小Tips:優(yōu)先級隊列中出數(shù)據(jù),出的是堆頂?shù)臄?shù)據(jù),堆頂?shù)臄?shù)據(jù)也就是容器中的第一個數(shù)據(jù),如果底層容器是 vector 那么堆頂?shù)臄?shù)據(jù)就是下標為 0 的數(shù)據(jù),出堆頂?shù)臄?shù)據(jù)不能直接使用頭刪,這樣會導(dǎo)致后面數(shù)據(jù)的父子關(guān)系全亂了。正確的做法是,將堆頂?shù)臄?shù)據(jù)和容器中的最后一個數(shù)據(jù)交換,然后執(zhí)行 pop_back 去刪除,最后還需要從根節(jié)點開始執(zhí)行一次向下調(diào)整,讓交換到堆頂?shù)臄?shù)據(jù)去到它應(yīng)該去的地方。

3.3.6 empty

bool empty()
{
	return _con.size() == 0;
}

3.3.7 size

size_t size()
{
	return _con.size();
}

四、結(jié)語

今天的分享到這里就結(jié)束啦!如果覺得文章還不錯的話,可以三連支持一下,春人的主頁還有很多有趣的文章,歡迎小伙伴們前去點評,您的支持就是春人前進的動力!

【C++雜貨鋪】優(yōu)先級隊列的使用指南與模擬實現(xiàn),C++雜貨鋪,c++,開發(fā)語言,優(yōu)先級隊列,堆,熱門文章來源地址http://www.zghlxwxcb.cn/news/detail-708543.html

到了這里,關(guān)于【C++雜貨鋪】優(yōu)先級隊列的使用指南與模擬實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【C++雜貨鋪】內(nèi)管管理

    【C++雜貨鋪】內(nèi)管管理

    目錄 ??前言?? ?? C/C++中內(nèi)存分布 ?? new 和 delete的使用 ?? new 和 delete的優(yōu)點 ?? new 和 delete的原理 ??? operator new 和 operator delete函數(shù) ??? 內(nèi)置類型 ??? 自定義類型 ?? 內(nèi)存泄漏 ?? 總結(jié) ? ? ? ? 歡迎收看本期【C++雜貨鋪】,本期內(nèi)容講解C++內(nèi)存管理。包含了C++中內(nèi)存

    2024年04月14日
    瀏覽(34)
  • 【C++雜貨鋪】拷貝構(gòu)造函數(shù)

    【C++雜貨鋪】拷貝構(gòu)造函數(shù)

    ?? 定義 拷貝構(gòu)造函數(shù) 是構(gòu)造函數(shù)的一個重載 ,它的本質(zhì)還是 構(gòu)造函數(shù) ,那就意味著,只有在創(chuàng)建對象的時候,編譯器才會自動調(diào)用它,那他和普通的構(gòu)造函數(shù)有什么區(qū)別呢? 拷貝構(gòu)造函數(shù),是創(chuàng)建對象的時候,用一個已存在的對象,去初始化待創(chuàng)建的對象 。簡單來說,

    2024年02月16日
    瀏覽(22)
  • 【C++雜貨鋪】詳解string

    【C++雜貨鋪】詳解string

    目錄 ???前言?? ?? 為什么學(xué)習(xí)string ?? 認識string(了解) ?? string的常用接口 ??? 構(gòu)造函數(shù) ??? string類對象的容量操作 ??? string類對象的訪問以及遍歷操作?編輯 ??? string類對象的修改操作 ?? 模擬實現(xiàn)string ?? 總結(jié) ? ? ? ? 歡迎觀看本期【C++雜貨鋪】,本期內(nèi)容

    2024年03月20日
    瀏覽(25)
  • 【C++雜貨鋪】詳解list容器

    【C++雜貨鋪】詳解list容器

    目錄 ??前言?? ?? 介紹 ?? 使用 ??? 構(gòu)造 ??? 迭代器iterator ??? capacity ??? modifiers ??? 迭代器失效 ?? 模擬實現(xiàn) ??? 迭代器的實現(xiàn) ?? 代碼展示 ?? 和vector的區(qū)別 ?? 總結(jié) ? ? ? ? 歡迎收看本期【C++雜貨鋪】,本期內(nèi)容將講解STL中關(guān)于list的內(nèi)容,會分為一下幾個方

    2024年04月14日
    瀏覽(22)
  • 【C++雜貨鋪】缺省參數(shù)、函數(shù)重載

    【C++雜貨鋪】缺省參數(shù)、函數(shù)重載

    ?缺省參數(shù)是 聲明或定義函數(shù)時為函數(shù)的參數(shù)指定一個缺省值 。在調(diào)用該函數(shù)時,如果沒有指定實參則采用該形參的缺省值,否則使用指定的實參。 ?上面代碼在 fun 函數(shù)的形參部分給了缺省值10,這意味著在調(diào)用 fun 函數(shù)的時候可以傳參,也可以不傳參,如果傳參了那形參

    2024年02月16日
    瀏覽(18)
  • 【C++雜貨鋪】運算符重載

    【C++雜貨鋪】運算符重載

    本文將以日期類為基礎(chǔ),去探尋運算符重載的特性與使用方法,下面先給出日期類的基礎(chǔ)定義: 備注 :拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù),均可以不寫,因為當(dāng)前日期類的三個成員變量都是內(nèi)置類型,沒有動態(tài)申請空間,使用淺拷貝就可以。 ?? 如何比較兩個日期的大??? 現(xiàn)如今,

    2024年02月16日
    瀏覽(22)
  • 【C++雜貨鋪】C++介紹、命名空間、輸入輸出

    【C++雜貨鋪】C++介紹、命名空間、輸入輸出

    ?C語言是 結(jié)構(gòu)化 和 模塊化 的語言,適合處理 較小規(guī)模 的程序。對于復(fù)雜的問題,規(guī)模較大的程序,需要高度的抽象和建模時,C語言則不合適。為了解決軟件危機,20世紀80年代,計算機界提出了 OOP (object oriented programming: 面向?qū)ο?)思想,支持面向?qū)ο蟮某绦蛟O(shè)計語言應(yīng)

    2024年02月16日
    瀏覽(31)
  • 【C++雜貨鋪】再談類和對象

    【C++雜貨鋪】再談類和對象

    在創(chuàng)建對象的時候,編譯器通過調(diào)用構(gòu)造函數(shù),在構(gòu)造函數(shù)體中,給對象中的各個成員變量一個合適的初值。 雖然上述構(gòu)造函數(shù)調(diào)用之后,對象中已經(jīng)有了一個初始值,但是不能將其稱為對對象中成員變量的初始化, 構(gòu)造函數(shù)體中的語句只能將其稱為賦初值,而不能稱作初

    2024年02月16日
    瀏覽(15)
  • 【C++雜貨鋪】初識類和對象

    【C++雜貨鋪】初識類和對象

    ?? 面向過程 C語言是 面向過程的 ,關(guān)注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題。以洗衣服這件事為例,下圖是C語言完成洗衣服這件事的過程。 ?? 面向?qū)ο?C++是 基于面向?qū)ο蟮?,關(guān)注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完

    2024年02月16日
    瀏覽(23)
  • 優(yōu)先級隊列【C++】

    優(yōu)先級隊列【C++】

    優(yōu)先隊列(priority_queue)也是隊列的一種,priority_queue的接口是和queue的接口是相同的。所以兩者的使用語法也是相同的。我們直接看優(yōu)先隊列(priority——queue)的底層實現(xiàn)原理。 默認情況下priority_queue是大堆。 priority_queue的底層實際上就是堆,模擬實現(xiàn)priority_queue之前,需要

    2024年02月10日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包