1. 程式人生 > >快速求棧或佇列中的最大值

快速求棧或佇列中的最大值

1.棧中最大值

       棧是按順序壓入,我們維護另外一個棧來記錄棧當前的最大值。如果push值大於輔助棧的頭元素,則輔助棧中壓入要push的值,否則重複壓入輔助棧的頭元素。

       

       簡單來說:push的時候兩個棧都push,max棧push的時候要比較要push的元素和棧頂元素的大小,誰大push誰。程式碼參考如下。(這種情況下我們維護的max棧的大小和data棧的大小相同)

#include<iostream>
#include<stack>
using namespace std;

template<typename T>
class Cstack
{
private: stack<T>s;
		 stack<T>maxs;
public: void pushV(T& value);
		void popV();
		T& getPeek();
		T& getMax();
};

template<typename T>
void Cstack::pushV(T &value)
{
	if(s.empty())
	{
		s.push(value);
		maxs.push(value);
	}
	else
	{
		s.push(value);
		int tmp=maxs.top();
		if(tmp>value)maxs.push(tmp);
		else maxs.push(value);
	}
}

template<typename T>
void Cstack::popV()
{
	if(s.empty())
		throw("empty stack!");
	s.pop();
	maxs.pop();
}

template<typename T>
T & Cstack::getPeek()
{
	if(s.empty())
		throw("empty stack!");
	return s.top();
}

template<typename T>
T& Cstack::getMax()
{
	if(s.empty())
		throw("empty stack!");
	return maxs.top();
}

       當然有優化的地方,就是空間上maxs棧不用儲存連續相同的最大值。也有看到用陣列來類比棧的,另外一個數組來記錄最大值的位置,基本上思想是一樣的。

2.佇列的最大值

       如果說棧增長的方向是單方向的,在push新元素時,只用更新新push元素所對應的最大值即可,因為之前壓入不受後壓入的元素的影響。影響只有:新壓入元素受已壓入元素的最大值的影響。已壓入元素對應的最大值不受影響。

       佇列不同,新壓入元素的對應的最大值不受已壓入元素的影響(因為他們會先pop),也就是他們僅和當前壓入元素相關。複雜的是已壓入的元素會受新壓入 元素的影響。那麼解決方案有兩種。

       第一種,用multiset記錄佇列中的元素,push時insert集合,pop時刪除相關值,求最大值時利用集合自動排序即可獲得。

       第二種:先來看下兩個棧實現一個佇列。這時我先說這兩個棧一個是資料棧,一個是輸出棧。push、pop的操作文中寫了,那麼如何求最大值呢?

        資料棧和輸出棧分別維護一個最大值棧,如棧中快速求取最大值的方法(1)。思路如下:

        

       兩個佇列實現一個棧的程式碼有了,只是在push的時候注意data1和max1捆綁,data2和max2捆綁。pop時也一樣。求最大值時要在max1和max2中求最大的。