如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

這篇文章主要講解了“如何使用Java堆棧實(shí)現(xiàn)隊(duì)列”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何使用Java堆棧實(shí)現(xiàn)隊(duì)列”吧!

創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)與策劃設(shè)計(jì),港北網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:港北等地區(qū)。港北做網(wǎng)站價(jià)格咨詢:13518219792

Example:

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);  
queue.peek();  // returns 1
queue.pop();   // returns 1
queue.empty(); // returns false

Notes:

  • You must use only standard operations of a stack -- which means only push to toppeek/pop from topsize, and is empty operations are valid.

  • Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.

  • You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).

解題思路

讀完題之后,第一步必然要想清楚棧和隊(duì)列的區(qū)別,如下圖所示,棧和隊(duì)列的基本實(shí)現(xiàn)其實(shí)都可以看作一個(gè)list:

1)那如果是棧的話,[1, 2, 3]入棧之后,指針會(huì)指向3,出棧的時(shí)候就會(huì)pop這個(gè)list里的3;

2)如果是隊(duì)列的話,[1, 2, 3]入隊(duì)之后,指針會(huì)指向1,出隊(duì)的時(shí)候就會(huì)pop這個(gè)list里的1。

也就是說(shuō)如果是棧,這個(gè)list里從上到下會(huì)是[3, 2, 1],而如果是隊(duì)列,則是[1, 2, 3]。因此,問題就轉(zhuǎn)化為:怎么將一個(gè)插入之后會(huì)變成[3, 2, 1]的list變成插入之后是[1, 2, 3]。

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

這個(gè)問題一下子很難找到答案,我們退一步思考另外一個(gè)問題:假如現(xiàn)在已經(jīng)是[1, 2, 3],現(xiàn)在要將4這個(gè)元素插入到這個(gè)list里面,怎么才能保持[1, 2, 3, 4]?(正如下圖所示)

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

為了解決這個(gè)問題,就需要將4插入到這個(gè)list的底部(而不能直接插入到頂部),那什么情況下4才能插入到底部?注意到這個(gè)list是一個(gè)棧,只有這個(gè)棧是空棧的情況下,4才有可能插入到底部。所以,我們要構(gòu)造出空棧的情況,那如果要將一個(gè)非空的棧變成空棧,勢(shì)必要pop元素,而且這些元素還必須保存起來(lái),不能丟棄,所以必然要有一個(gè)地方,必然要有另外一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)這些pop出來(lái)的元素。

基于上面的思考過程,我們自然會(huì)想到額外再使用一個(gè)棧

來(lái)存儲(chǔ)這些pop出來(lái)的元素,如下圖所示。將主棧stack2的元素逐一pop出來(lái)并且push到輔助棧stack1中,就可以清空主棧,讓它變成一個(gè)空棧。

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

這樣一來(lái),主棧就可以將新的元素4放入到底部。與此同時(shí),因?yàn)樵剡M(jìn)入輔助棧stack1之后,順序變成了逆序[3, 2, 1],所以當(dāng)這些元素再pop出來(lái)導(dǎo)到主棧stack2時(shí),又會(huì)跟原來(lái)的順序[1, 2, 3]一樣。

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

至此,整個(gè)算法的邏輯就清晰了,我們來(lái)重新過一遍。首先,當(dāng)主棧stack2沒有元素的時(shí)候,那就直接放入主棧stack2即可。

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

接下來(lái)會(huì)進(jìn)來(lái)第二個(gè)元素2,那就按照如下的步驟走:

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

當(dāng)新元素3要插入的時(shí)候,繼續(xù)這個(gè)操作即可:

如何使用Java堆棧實(shí)現(xiàn)隊(duì)列

可以看到,通過這種方法,可以始終保持主棧是以隊(duì)列的順序存儲(chǔ)元素(參考本文的第一幅圖)。至于pop和peek方法,都只要直接對(duì)主棧stack2進(jìn)行判斷和處理就可以了。

時(shí)間復(fù)雜度

按照上面的解法,隊(duì)列的各種基本操作的時(shí)間復(fù)雜度分別為:

push操作:整個(gè)過程需要將元素從主棧stack2挪到輔助棧stack1(這一步的時(shí)間復(fù)雜度是O(n)),然后插入新元素(時(shí)間復(fù)雜度O(1)),最后再挪回主棧stack2(時(shí)間復(fù)雜度O(n)),所以時(shí)間復(fù)雜度是O(2n+1),等于O(n)

pop操作:因?yàn)橹恍枰獙?duì)主棧stack2做判斷,所以只需要O(1)

peek操作:因?yàn)橹恍枰獙?duì)主棧stack2做判斷,所以只需要O(1)

最終實(shí)現(xiàn)

Java實(shí)現(xiàn)
class MyQueue {

        private LinkedList<Integer> stack1 = new LinkedList<>(); // the aux one
        private LinkedList<Integer> stack2 = new LinkedList<>(); // the true one

        /**
         * Initialize your data structure here.
         */
        public MyQueue() {
        }

        /**
         * Push element x to the back of queue.
         */
        public void push(int x) {
            if (stack2.isEmpty()) {
                stack2.push(x);
            } else {
                while (!stack2.isEmpty()) {
                    stack1.push(stack2.pop());
                }
                stack2.push(x);
                while (!stack1.isEmpty()) {
                    stack2.push(stack1.pop());
                }
            }
        }

        /**
         * Removes the element from in front of queue and returns that element.
         */
        public int pop() {
            if (!stack2.isEmpty()) {
                return stack2.pop();
            }
            return -1;
        }

        /**
         * Get the front element.
         */
        public int peek() {
            if (!stack2.isEmpty()) {
                return stack2.peek();
            }
            return -1;
        }

        /**
         * Returns whether the queue is empty.
         */
        public boolean empty() {
            return stack2.isEmpty();
        }
    }

感謝各位的閱讀,以上就是“如何使用Java堆棧實(shí)現(xiàn)隊(duì)列”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)如何使用Java堆棧實(shí)現(xiàn)隊(duì)列這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

當(dāng)前名稱:如何使用Java堆棧實(shí)現(xiàn)隊(duì)列
當(dāng)前地址:http://m.kartarina.com/article48/pppihp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化響應(yīng)式網(wǎng)站品牌網(wǎng)站設(shè)計(jì)外貿(mào)網(wǎng)站建設(shè)網(wǎng)頁(yè)設(shè)計(jì)公司品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
主站蜘蛛池模板: 亚洲AV无码一区二区三区国产 | 亚洲午夜福利AV一区二区无码| 亚洲区日韩区无码区| 亚洲精品中文字幕无码A片老| 久久亚洲AV成人出白浆无码国产| 久久久久亚洲精品无码蜜桃| 亚洲精品无码乱码成人| 久久亚洲精品无码AV红樱桃| 亚洲AV无码成人精品区日韩| 亚洲AV无码一区二三区| 久久无码高潮喷水| 亚洲高清无码综合性爱视频| 无码人妻精品中文字幕免费| 亚洲国产91精品无码专区| 无码孕妇孕交在线观看| 亚洲成A人片在线观看无码3D| 色欲香天天综合网无码| 精品无码人妻一区二区免费蜜桃| 国产精品无码2021在线观看| 人妻少妇AV无码一区二区| 天堂一区人妻无码| 久久无码专区国产精品s| 色欲A∨无码蜜臀AV免费播| 久久无码AV中文出轨人妻| 无码人妻精品一区二区三区夜夜嗨| 亚洲中文字幕伊人久久无码| 亚洲国产无套无码av电影| 亚洲av日韩av高潮潮喷无码| 无码人妻久久一区二区三区免费| 国产乱子伦精品无码码专区| 中文无码一区二区不卡αv| 国产成人无码网站| 精品久久久久久无码不卡| 无码中文人妻在线一区| 亚洲爆乳精品无码一区二区三区| 无码少妇一区二区三区浪潮AV| 亚洲av无码兔费综合| 国产办公室秘书无码精品99| 亚洲av无码专区在线| 日韩一区二区三区无码影院 | 国产成年无码AV片在线韩国|