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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

队列实现栈 | 栈实现队列

發(fā)布時間:2024/4/11 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 队列实现栈 | 栈实现队列 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

隊列實現(xiàn)棧 | 棧實現(xiàn)隊列

?、 ?棧實現(xiàn)隊列

首先,隊列的 API 如下:

class MyQueue {/** 添加元素到隊尾 */public void push(int x);/** 刪除隊頭的元素并返回 */public int pop();/** 返回隊頭元素 */public int peek();/** 判斷隊列是否為空 */public boolean empty(); }

我們使?兩個棧 s1, s2 就能實現(xiàn)?個隊列的功能(這樣放置棧可能更容易理解) :

class MyQueue {private Stack<Integer> s1, s2;public MyQueue() {s1 = new Stack<>();s2 = new Stack<>();}// ... }

當調用 push 讓元素入隊時,只要把元素壓入 s1 即可,比如說 push 進 3 個元素分別是 1,2,3,那么底層結構就是這樣:

/** 添加元素到隊尾 */ public void push(int x) {s1.push(x); }

那么如果這時候使用 peek 查看隊頭的元素怎么辦呢?按道理隊頭元素應該是 1,但是在 s1 中 1 被壓在棧底,現(xiàn)在就要輪到 s2 起到一個中轉的作用了:當 s2 為空時,可以把 s1 的所有元素取出再添加進 s2,這時候 s2 中元素就是先進先出順序了。

/** 返回隊頭元素 */ public int peek() {if (s2.isEmpty())// 把 s1 元素壓入 s2while (!s1.isEmpty())s2.push(s1.pop());return s2.peek(); }

同理,對于 pop 操作,只要操作 s2 就可以了

/** 刪除隊頭的元素并返回 */ public int pop() {// 先調用 peek 保證 s2 非空peek();return s2.pop(); }

最后,如何判斷隊列是否為空呢?如果兩個棧都為空的話,就說明隊列為空:

/** 判斷隊列是否為空 */ public boolean empty() {return s1.isEmpty() && s2.isEmpty(); }

C++代碼:

class MyQueue { public: //主要思想是定義兩個棧,一個用來存放入隊元素的棧s1,另一個棧 //用來進行出隊操作的s2,往隊列中插元速時,直接往s1中插入,出隊時, //如果s2不為空,直接在s2中進行出棧操作,如果s2為空,就把s1中元素全部放到s2中/** Initialize your data structure here. */MyQueue() {}/** Push element x to the back of queue. */void push(int x) {//直接往s1中插入s1.push(x);}/** Removes the element from in front of queue and returns that element. */int pop() {//進行出隊操作時,如果s2為空,就直接把s1中元素先移動到s2中,//在進行出隊操作,如果s2不為空,直接在s2中直接出隊,注意不能在s2有//元素時把s1中的元素移動到s2中,這樣順序回亂int data;if(s2.empty()){while(s1.size()){s2.push(s1.top());s1.pop();}data = s2.top();s2.pop();}else{data = s2.top();s2.pop();}return data;}/** Get the front element. */int peek() {int data;if(s2.empty()){while(s1.size()){s2.push(s1.top());s1.pop();}data = s2.top();//s2.pop();}else{data = s2.top();//s2.pop();}return data;}/** Returns whether the queue is empty. */bool empty() {return s1.empty() && s2.empty();}private:stack<int> s1;stack<int> s2; };

二、用隊列實現(xiàn)棧

首先看下棧的 API:

class MyStack {/** 添加元素到棧頂 */public void push(int x);/** 刪除棧頂?shù)脑夭⒎祷?*/public int pop();/** 返回棧頂元素 */public int top();/** 判斷棧是否為空 */public boolean empty(); }

先說 push API,直接將元素加入隊列,同時記錄隊尾元素,因為隊尾元素相當于棧頂元素,如果要 top 查看棧頂元素的話可以直接返回:

class MyStack {Queue<Integer> q = new LinkedList<>();int top_elem = 0;/** 添加元素到棧頂 */public void push(int x) {// x 是隊列的隊尾,是棧的棧頂q.offer(x);top_elem = x;}/** 返回棧頂元素 */public int top() {return top_elem;} }

我們的底層數(shù)據(jù)結構是先進先出的隊列,每次 pop 只能從隊頭取元素;但是棧是后進先出,也就是說 pop API 要從隊尾取元素。

解決方法簡單粗暴,把隊列前面的都取出來再加入隊尾,讓之前的隊尾元素排到隊頭,這樣就可以取出了:

/** 刪除棧頂?shù)脑夭⒎祷?*/ public int pop() {int size = q.size();while (size > 1) {q.offer(q.poll());size--;}// 之前的隊尾元素已經(jīng)到了隊頭return q.poll(); }

這樣實現(xiàn)還有一點小問題就是,原來的隊尾元素被提到隊頭并刪除了,但是 top_elem 變量沒有更新,我們還需要一點小修改:

/** 刪除棧頂?shù)脑夭⒎祷?*/ public int pop() {int size = q.size();// 留下隊尾 2 個元素while (size > 2) {q.offer(q.poll());size--;}// 記錄新的隊尾元素top_elem = q.peek();q.offer(q.poll());// 刪除之前的隊尾元素return q.poll(); }

最后,API empty 就很容易實現(xiàn)了,只要看底層的隊列是否為空即可:

/** 判斷棧是否為空 */ public boolean empty() {return q.isEmpty(); }

當然可以用兩個隊列來實現(xiàn)一個棧:

C++代碼:

class MyStack { public: //主要思想是定義兩個隊列,入棧時,如果兩個隊列同時為空,就隨便往一個隊列中插入 //如果其中有一個隊列不為空,每次插就往非空的隊列中插入。出棧時,每次把非空隊列的 //前size-1個元素移動到空隊列中,原非空隊列就只剩下最后一個元素,這個元素滿 //足棧的要求,直接出隊??傊?#xff0c;主要思想是把兩個隊列中的元素來回移動,每次剩下最后 //一個元素直接出隊,就相當于是棧頂元素/** Initialize your data structure here. */MyStack() {queue<int> q1;queue<int> q2;}/** Push element x onto stack. */void push(int x) {//如果兩個隊列都為空,隨便插入到一個隊列中,反之插入到非空隊列中if(!q1.empty()){q1.push(x);}else{q2.push(x);}}/** Removes the element on top of the stack and returns that element. */int pop() {//每次把非空隊列中的前size-1個元素移動到空隊列中去,原非空隊列//剩下最后一個元素就相當于棧頂元素,出棧時,就直接出隊int data; if(q1.empty()){while(q2.size() > 1){q1.push(q2.front());q2.pop();}data = q2.front();q2.pop();}else{while(q1.size() > 1){q2.push(q1.front());q1.pop();}data = q1.front();q1.pop();}return data;}/** Get the top element. */int top() {//返回非空隊列的隊尾元素,就相當于棧頂元素,if(!q1.empty()){return q1.back();}else{return q2.back();}}/** Returns whether the stack is empty. */bool empty() {//兩個隊列同時為空是,此時才表明棧中沒有任何元素return q1.empty() && q2.empty();}private:queue<int> q1;queue<int> q2; };

總結

以上是生活随笔為你收集整理的队列实现栈 | 栈实现队列的全部內容,希望文章能夠幫你解決所遇到的問題。

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