1.佇列實現棧以及棧實現佇列
阿新 • • 發佈:2022-05-22
佇列實現棧以及棧實現佇列
佇列和棧就是操作受限的資料結構
因為佇列和棧底層就是陣列和連結串列封裝的,只暴露頭尾操作的API。
佇列主要在BFS演算法,棧主要用在括號相關的問題
佇列:先進先出
棧:先進後出
用棧實現佇列
呼叫 push 入隊時,只要把元素壓縮S1即可,peek檢視隊頭時,當S2為空時,可以把S1所有元素取出再新增進S2,這時就是先進先出順序
同理,對於pop操作,只要操作S2既可以
如果兩個棧都為空,說明佇列為空
peek 操作,調⽤它時可能觸發 while 循 環,這樣的話時間複雜度是 O(N),但是⼤部分情況下 while 迴圈不會被觸發,時間複雜度是 O(1)。
由於pop 操作調⽤了 peek,它的時間複雜度和 peek 相同。 像這種情況,可以說它們的最壞時間複雜度是 O(N),因為包含 while 迴圈,可能需要從 s1 往 s2 搬移元 素。
但是它們的均攤時間複雜度是 O(1),這個要這麼理解:對於⼀個元素,最多隻可能被搬運⼀次,也就是說peek 操作平均到每個元素的時間複雜度是 O(1)。
class MyQueue { private Stack<Integer> s1,s2; public MyQueue() { s1 = new Stack<>(); s2 = new Stack<>(); } public void push(int x) {//新增元素到隊尾 s1.push(x); } public int pop() {//刪除隊頭的元素並返回 peek();//先呼叫peek保證s2非空 return s2.pop(); } public int peek() {//返回隊頭元素 if(s2.isEmpty()){ while(!s1.isEmpty()){//s1不是空的 s2.push(s1.pop()); } } return s2.peek(); } public boolean empty() {//判斷佇列是否為空 return s1.isEmpty() && s2.isEmpty(); } }
用佇列實現棧
⽤佇列實現棧就⽐較簡單粗暴了,只需要⼀個佇列作為底層資料結構
class MyStack { Queue<Integer> q = new LinkedList<>(); int top_elem = 0; public MyStack() { } public void push(int x) {//新增元素到棧頂 q.offer(x); top_elem = x;//隊尾為棧頂 } public int pop() {//刪除棧頂元素並返回 int size = q.size(); while(size >2){//留下隊尾2個元素 q.offer(q.poll()); size--; } top_elem = q.peek();//記錄新的隊尾元素 q.offer(q.poll()); return q.poll();//刪除之前的隊尾元素 } public int top() {//返回棧頂元素 return top_elem; } public boolean empty() {//判斷棧是否為空 return q.isEmpty(); } }