棧與隊列的應用
在“棧與隊列的應用(上)”中,通過討論兩個隊列實現一個棧和兩個棧實現一個隊列這兩個問題,我們對棧和隊列也有了更深的瞭解,下面我們主要來討論以下兩個面試中常常會遇到的問題:
1)一個數組實現兩個棧
2)實現一個棧,能夠push、pop、min(求棧中最小的數據)
問題一:
對於一個數組,我們如何能夠使其成爲兩個棧?根據數組和棧的特點,我們不難發現可以將數組的兩端作爲棧的棧底,使用兩個指針分別指向數組的開始位置和末尾位置,假設將數組的左邊作爲棧s1,數組的右邊作爲棧s2,若s1中的棧頂指針向後在偏移一個位置與另一個指針同時指向一塊空間,此時就稱爲“棧滿”,不能進行插入操作。如果想要對棧進行操作,就必須要指定對哪個棧操作。這裏使用了兩個整形變量用來記錄棧s1和棧s2的棧頂的位置下標,對其進行操作。
下面爲簡單的圖示:
下面是具體的程序代碼:
//一個數組實現兩個棧
//方法一:(靜態數組)
#include <iostream>
using namespace std;
#include <stdlib.h>
#define MAX 100
template <class T>
class TwoStack
{
public:
TwoStack() //構造函數
:_array(new T[MAX])
, lefttop0(-1)
, righttop1(MAX)
{ }
public:
void Push(T x, int i) //壓棧,將數據壓入i號棧中
{
if (lefttop0 + 1 == righttop1)
{
cout << "棧已滿,不能壓棧!";
return;
}
else
{
switch (i)
{
case 0: //壓入0號棧中
lefttop0++;
_array[lefttop0] = x;
break;
case 1: //壓入1號棧中
righttop1--;
_array[righttop1] = x;
break;
default:
break;
}
}
}
void Pop(int i) //i號棧、元素出棧
{
switch (i)
{
case 0:
if (lefttop0 == -1)
{
cout << "The Stack is Empty!" << endl;
}
lefttop0--;
break;
case 1:
if (righttop1 == MAX)
{
cout << "The Stack is Empty!" << endl;
}
righttop1++;
break;
default:
break;
}
}
T& top(int i) //讀取i號棧中元素
{
if (i == 0)
{
return _array[lefttop0];
}
else
{
return _array[righttop1];
}
}
void Display(int i) //打印i號棧的元素
{
if (i == 0)
{
cout << "打印0號棧中的元素:" << endl;
while (lefttop0 != -1)
{
cout << _array[lefttop0] << " ";
lefttop0--;
}
cout << endl;
}
else if (i == 1)
{
cout << "打印1號棧中的元素:" << endl;
while (righttop1 != MAX)
{
cout << _array[righttop1] << " ";
righttop1++;
}
cout << endl;
}
}
private:
T* _array;
int lefttop0;
int righttop1;
};
問題二:
這個問題主要是要實現求棧中最小數據,完成這個功能,就需要藉助另一個棧對最小數據進行保存,假設現有棧s1和棧s2,當向s1中插入第一個數據時,同時也向s2中插入相同的數據,下來在向s1中插入第二個數據,此時若第二個數據小於s2的棧頂數據,此時也將與之相同的數據插入s2中,若第二個數據小於s2的棧頂數據,則不用向s2中插入數據,按照這樣的方式插入數據。現在就能夠顯而易見的知道s2中的棧頂數據就是棧s1中的最小數據。
如果需要對s1中數據進行刪除,如若s1中要刪除的數據與s2中要刪除的數據相同,則棧s2中同樣刪除棧頂元素,若不等,則將s1中棧頂元素刪除就行,不需要刪除s2中的數據。這樣就能夠始終保持s2中棧頂數據爲棧s1中的最小數據。
下面是簡單的圖示:
下面爲具體的程序代碼:
//判斷出對序列中的最小數據
//實現一個棧,要求實現Push、pop、min(返回棧中最小值)的時間複雜度爲o(1)。
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <stack>
template <class T>
class Stack
{
public:
void Push(const T& x)
{
if (s1.empty() && s2.empty())
{
s1.push(x);
s2.push(x);
}
else if (!s1.empty())
{
if (x < s2.top())
{
s1.push(x);
s2.push(x);
}
else
{
s1.push(x);
}
}
}
void Pop()
{
if (!s1.empty() && !s2.empty())
{
if (s1.top() == s2.top())
{
s1.pop();
s2.pop();
}
else
{
s1.pop();
}
}
}
T minNumber()
{
return s2.top();
}
private:
stack<T> s1;
stack<T> s2;
};
本文出自 “無心的執着” 博客,謝絕轉載!