您好,登錄后才能下訂單哦!
本篇內容主要講解“Java棧與隊列怎么實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java棧與隊列怎么實現”吧!
【OJ鏈接】
循環隊列一般通過數組實現。我們需要解決幾個問題。
a、下標最后再往后(offset 小于 array.length): index = (index + offset) % array.length。通俗一點,就是如果我們的數組大小為8,下標走到了7,再往后如何回到0,我們可以(index+1)%8來實現。
b、下標最前再往前的時候,我們特殊判斷一下,將其置為數組大小減一即可。
我們可以給數組預留一個位置,如果rear+1=front,則表示隊列已滿;如果rear=front,表示隊列為空。這個情況下,我們需要考慮隊列大小的問題,在定義數組大小時,需要比原有的大一。
【代碼如下】
class MyCircularQueue { public int front; public int rear; public int[] array; //構造方法 public MyCircularQueue(int k) { //因為預留位置的緣故,數組的大小要定義為k+1 this.array=new int[k+1]; } //入隊 public boolean enQueue(int value) { if(isFull()){ return false; } this.array[this.rear]=value; this.rear=(this.rear+1)%this.array.length; return true; } //出隊 public boolean deQueue() { if(isEmpty()){ return false; } this.front=(this.front+1)%this.array.length; return true; } //獲取隊頭 public int Front() { if(isEmpty()){ return -1; } return this.array[front]; } //獲取隊尾 public int Rear() { if(isEmpty()){ return -1; } int index=-1; if(this.rear==0){ index=this.array.length-1; }else{ index=this.rear-1; } return this.array[index]; } //判斷是否為空 public boolean isEmpty() { if(this.front==this.rear){ return true; } return false; } //判斷隊列是否滿 public boolean isFull() { if((this.rear+1)%this.array.length==this.front){ return true; } return false; } }
【OJ鏈接】
因為棧的先進后出、隊列的先進先出原則。我們需要兩個隊列來實現棧。當兩個隊列都為空時,棧為空。
入棧(push):第一次入棧無所謂,兩個隊列都為空,隨便選擇一個隊列入隊即可;后面入棧時,肯定會有一個隊列不為空,找到不為空的隊列,進行入隊操作。
出棧(pop):首先棧為空時,不能進行出棧操作;棧不為空時,肯定有一個隊列為空(queue1),一個隊列不為空(queue2),將queue1中的size-1個元素出棧到queue2中(特別注意不能將求queue1大小的函數放進循環里,queue進行出隊操作時,其大小是改變的),最后將queue1中最后一個元素進行出隊最為返回值。
獲取棧頂元素(top):和出棧差不多,就不細說了
【代碼如下】
class MyStack { private Queue<Integer> queue1; private Queue<Integer> queue2; //構造方法 public MyStack() { queue1=new LinkedList<>(); queue2=new LinkedList<>(); } //入棧 public void push(int x) { if(!queue2.isEmpty()){ queue2.offer(x); }else{ queue1.offer(x); } } //出棧 public int pop() { if(empty()){ return -1; } if(queue1.isEmpty()){ int size=queue2.size(); for(int i=0;i<size-1;++i){ int x=queue2.poll(); queue1.offer(x); } return queue2.poll(); }else{ int size=queue1.size(); for(int i=0;i<size-1;++i){ int x=queue1.poll(); queue2.offer(x); } return queue1.poll(); } } //獲取棧頂元素 public int top() { if(empty()){ return -1; } if(queue1.isEmpty()){ int x=-1; int size=queue2.size(); for(int i=0;i<size;++i){ x=queue2.poll(); queue1.offer(x); } return x; }else{ int size=queue1.size(); int x=-1; for(int i=0;i<size;++i){ x=queue1.poll(); queue2.offer(x); } return x; } } //判斷棧是否為空 public boolean empty() { if(queue1.isEmpty()&&queue2.isEmpty()){ return true; } return false; } }
【OJ鏈接】
還是和上面一樣,需要用到兩個棧(stack1、stack2)。和實現棧列不同的是,入隊只能對同一個棧進行操作。如果兩個棧都為空,則隊列為空。
入隊(push):規定stack1用來入隊。每次入隊時,對stack1進行入棧操作即可。
出隊(pop):規定stack2進行出隊操作。如果隊列為空時,不能進行出隊操作。當stack2為空時,我們需要將stack1中所有元素出棧,放入stack2中,然后對stack2進行出棧操作。如果stack2不為空,則直接對stack2進行出棧操作即可。
獲取隊列開頭元素(peek):和出棧操作相同,最后只需要獲取stack2的棧頂元素即可。
【代碼如下】
class MyQueue { private Stack<Integer> stack1; private Stack<Integer> stack2; //構造方法 public MyQueue() { stack1=new Stack<>(); stack2=new Stack<>(); } //入隊操作 public void push(int x) { stack1.push(x); } //出隊操作 public int pop() { if(stack2.empty()){ int size=stack1.size(); for(int i=0;i<size;++i){ int x=stack1.pop(); stack2.push(x); } } return stack2.pop(); } //獲取隊列開頭的元素 public int peek() { if(stack2.empty()){ int size=stack1.size(); for(int i=0;i<size;++i){ int x=stack1.pop(); stack2.push(x); } } return stack2.peek(); } //判斷隊列是否為空 public boolean empty() { if(stack1.empty()&&stack2.empty()){ return true; } return false; } }
【OJ鏈接】
其實就是要在O(1)的時間復雜度內找到棧的最小元素。需要兩個棧來實現,一個棧來進行出棧、入棧操作。只需要保證不管如何操作,另一個棧的棧頂元素都是當前棧的最小元素即可。
兩個棧stack1、stack2,站的操作都在stack1中:
入棧:如果第一次入棧,我們需要將其也放入stack2中,之后的入棧,將入棧元素與stack2的棧頂元素進行比較,如果其小于stack2的棧頂元素,則將其放入stack2中。
出棧:對stack1出棧時,將其與stack2的棧頂元素進行比較,如果其等于stack2的棧頂元素,則對stack2進行出棧操作。
這樣就能保證stack2的棧頂元素總是stack1的最小元素。注意:如果stack1中入棧兩個相同的最小元素,都需要對stack2進行入棧。
【代碼如下】
class MinStack { private Stack<Integer> stack1; private Stack<Integer> stack2; //構造方法 public MinStack() { stack1=new Stack<>(); stack2=new Stack<>(); } //入棧 public void push(int val) { stack1.push(val); if(stack2.empty()){ stack2.push(val); }else{ if(val<=stack2.peek()){ stack2.push(val); } } } //出棧 public void pop() { int x=stack1.pop(); if(x==stack2.peek()){ stack2.pop(); } } //獲取棧頂元素 public int top() { return stack1.peek(); } //獲取棧的最小元素 public int getMin() { return stack2.peek(); } }
到此,相信大家對“Java棧與隊列怎么實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。