日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

栈结构的经典算法题

發(fā)布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈结构的经典算法题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

棧結(jié)構(gòu)

?

顛倒一個棧的元素順序

問題:假設(shè)有一個棧{1,2,3,4,5,6},6是棧頂,1是棧底,現(xiàn)在要把這個棧中的元素顛倒一下。

思路:最簡單的辦法當(dāng)然是把棧中的元素依次pop到一個數(shù)組中,然后把這個數(shù)組再push回棧里面即可,但這樣需要O(n)的輔助空間。

下面介紹一種僅使用O(1)輔助空間的算法,我們知道,可以使用遞歸來模擬棧的操作。我們借助函數(shù)遞歸pop元素,這樣在遞歸的函數(shù)棧上依次有

{6,5,4,3,2,1},1是棧頂,6是棧底,然后在遞歸返回的時候,如何把當(dāng)前元素塞到原棧的底部呢?這里借助了另一個遞歸!

?

C++代碼實(shí)現(xiàn)如下:

void Add2Bottom(stack<int> &s, int val) {int top;if (s.empty()) {s.push(val);} else {top = s.top();s.pop(); Add2Bottom(s, val);s.push(top);} }void Reverse(stack<int> &s) {int top;if (!s.empty()) {top = s.top();s.pop();Reverse(s);Add2Bottom(s, top);} }int main() {int n;int array[6] = {1,2,3,4,5,6};stack<int> s;for (n=0; n<6; n++) s.push(array[n]);Reverse(s);while (!s.empty()) {cout<<s.top()<<endl;s.pop();} }

?

棧的min函數(shù)

定義棧的數(shù)據(jù)結(jié)構(gòu),要求添加一個min函數(shù),能夠得到棧的最小元素。要求函數(shù)min、push以及pop的時間復(fù)雜度都是O(1)。

思路:利用輔助棧,每次對stack push/pop一個元素時,同時也要更新輔助棧(存儲最小元素的位置),例如:

?步驟????????????? 數(shù)據(jù)棧??????????? 輔助棧??????????????? 最小值
1.push 3??? 3????????? 0???????????? 3
2.push 4??? 3,4??????? 0,0?????????? 3
3.push 2??? 3,4,2????? 0,0,2???????? 2
4.push 1??? 3,4,2,1??? 0,0,2,3?????? 1
5.pop?????? 3,4,2????? 0,0,2???????? 2
6.pop?????? 3,4??????? 0,0?????????? 3
7.push 0??? 3,4,0????? 0,0,2???????? 0

?

C++代碼實(shí)現(xiàn):

#include <deque> #include <assert.h> #include <iostream>using namespace std;template <typename T> class CStackWithMin {public:CStackWithMin(void) {}virtual ~CStackWithMin(void) {}T& top(void);const T& top(void) const;void push(const T& value);void pop(void);const T& min(void) const;private:deque<T> m_data; // the elements of stackdeque<size_t> m_minIndex; // the indices of minimum elements };// get the last element of mutable stack template <typename T> T& CStackWithMin<T>::top() {return m_data.back(); }// get the last element of non-mutable stack template <typename T> const T& CStackWithMin<T>::top() const {return m_data.back(); }// insert an elment at the end of stack template <typename T> void CStackWithMin<T>::push(const T& value) {// append the data into the end of m_data m_data.push_back(value);// set the index of minimum elment in m_data at the end of m_minIndexif(m_minIndex.size() == 0) {m_minIndex.push_back(0);} else {if(value < m_data[m_minIndex.back()])m_minIndex.push_back(m_data.size() - 1);elsem_minIndex.push_back(m_minIndex.back());} }// erease the element at the end of stack template <typename T> void CStackWithMin<T>::pop() {// pop m_data m_data.pop_back();// pop m_minIndex m_minIndex.pop_back(); }// get the minimum element of stack template <typename T> const T& CStackWithMin<T>::min() const {assert(m_data.size() > 0);assert(m_minIndex.size() > 0);return m_data[m_minIndex.back()]; }

int main()
{
class CStackWithMin<int> stk;

stk.push(3);
cout<<"min="<<stk.min()<<endl;

stk.push(4);
cout<<"min="<<stk.min()<<endl;

stk.push(2);
cout<<"min="<<stk.min()<<endl;

stk.push(1);
cout<<"min="<<stk.min()<<endl;

stk.pop();
cout<<"min="<<stk.min()<<endl;

stk.pop();
cout<<"min="<<stk.min()<<endl;

stk.push(0);
cout<<"min="<<stk.min()<<endl;
}

?

?

?

?

棧的push、pop序列

輸入兩個整數(shù)序列,其中一個序列表示棧的push順序,判斷另一個序列有沒有可能是對應(yīng)的pop順序。為了簡單起見,我們假設(shè)push序列的任意兩個整數(shù)都是不相等的。?

比如輸入的push序列是1、2、3、4、5,那么4、5、3、2、1就有可能是一個pop系列。因?yàn)榭梢杂腥缦碌膒ush和pop序列:push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,這樣得到的pop序列就是4、5、3、2、1。但序列4、3、5、1、2就不可能是push序列1、2、3、4、5的pop序列。

?

?C++實(shí)現(xiàn):

int verify(int in[], int out[], int N) {int n; int m = 0;stack<int> s;for (n=0; n<N; n++) {s.push(in[n]); while (!s.empty()) {if (s.top() == out[m]) {s.pop(); m++;} else {break; } } } return s.empty(); }int main() {int ret;int in[5] = {1,2,3,4,5};int out[5] = {4,3,5,1,2};ret = verify(in, out, 5); cout<<"ret="<< ret<<endl; }

?

?

?

用棧實(shí)現(xiàn)隊(duì)列

設(shè)2 個棧為A和B,A用作入隊(duì),B用作出隊(duì)。
隊(duì)滿:A滿且B不為空;
隊(duì)空:A和B都為空;
入隊(duì)
(1) 如果A未滿,將新元素push 入棧A;
(2) 如果A已滿,將棧A中所有元素依次pop 出并push 到棧B,然后將元素入棧A;
出隊(duì)
(1) 如果B為空,則將棧A 中所有元素依次pop 出并push 到棧B,然后將元素出棧B;
(2) 如果B不為空,將棧B 的棧頂元素pop 出;

?

C++代碼實(shí)現(xiàn):

bool queue_empty(stack<int> &s1, stack<int> &s2) {return s1.empty() && s2.empty(); }void enqueue(stack<int> &s1, stack<int> &s2, int val) {s1.push(val); }void dequeue(stack<int> &s1, stack<int> &s2, int &val) {int top;if (s2.empty()) {while (!s1.empty()) {top = s1.top(); s1.pop();s2.push(top);} } if (!s2.empty()) {val = s2.top();s2.pop();} else {cout<<"error: queue is empty"<<endl;} }int main() {int n;int array[6] = {1,2,3,4,5,6};stack<int> s1; stack<int> s2; for (n=0; n<6; n++) enqueue(s1, s2, array[n]);while (!queue_empty(s1, s2)) {dequeue(s1, s2, n);cout<<n<<endl;}}

注意:這里沒有考慮棧空間可能滿的問題。

?

其實(shí),也可以用一個棧來模擬隊(duì)列結(jié)構(gòu),仍然是借助遞歸棧,每次往棧插入元素時,把它塞到棧底,這樣就實(shí)現(xiàn)了FIFO的隊(duì)列結(jié)構(gòu)。

代碼如下:

void enqueue2(stack<int> &s, int val) {int top;if (s.empty()) {s.push(val);} else {top = s.top();s.pop();enqueue2(s, val);s.push(top); } }int main() {int n;int array[6] = {1,2,3,4,5,6};stack<int> s;for (n=0; n<6; n++) enqueue2(s, array[n]); while (!s.empty()) {n = s.top();s.pop();cout<<n<<endl;} }

?

?

用隊(duì)列實(shí)現(xiàn)棧

?

設(shè)2 個隊(duì)列為A和B,A用作入隊(duì)/出隊(duì),B用作輔助。
隊(duì)滿:A滿且B不為空;
隊(duì)空:A和B都為空;
入棧:將新元素插入隊(duì)列A;
出棧
(1) 除最后一個元素外,將隊(duì)列A的元素全部插入到隊(duì)列B;
(2) 將隊(duì)列A的最后一個元素出隊(duì);

(3) 將隊(duì)列B的元素?fù)Q回到隊(duì)列A;

?

void stack_pop(queue<int> &q1, queue<int> &q2, int &n) {int i, head;while (!q1.empty()) {head = q1.front();q1.pop();if (q1.empty()) {n = head;} else {q2.push(head);}}while (!q2.empty()) {head = q2.front();q1.push(head);q2.pop();} }int main() {int n;int array[6] = {1,2,3,4,5,6};queue<int> q1, q2;for (n=0; n<6; n++) q1.push(array[n]);while (!q1.empty()) {stack_pop(q1, q2, n);cout<<n<<endl;} }

?

轉(zhuǎn)載于:https://www.cnblogs.com/chenny7/p/4126910.html

總結(jié)

以上是生活随笔為你收集整理的栈结构的经典算法题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。