1. 程式人生 > >【題9 用兩個棧實現佇列】

【題9 用兩個棧實現佇列】

【題9 用兩個棧實現佇列】
【題目】
用兩個棧實現佇列,佇列的宣告如下:請實現它的兩個函式appendTail和deleteHead分別完成在佇列尾部插入節點和在佇列頭部刪除節點的功能。
[分析]
插入:
向棧stack1 中插入a元素,此時stack1中有元素{a},stack2為空。再像stack1中壓入兩個元素b和c,此時stack1有元素{a,b,c},c位於棧頂,stack2為空。如圖a
刪除:
按照佇列先入先出原則,最先被刪除的應該是a,把stack1中元素逐個彈出並壓入stack2中,則元素在stack2中的順序為{c,b,a},此時彈出stack2的棧頂元素a。stack1為空。以此類推。
在這裡插入圖片描述


再插入一個 元素d。還是壓入到stack1中,如圖d,考慮下一次刪除佇列頭部stack2不為空,直接彈出它的棧頂元素c,如圖e,c的確時比d先進入佇列應該在d之前從佇列中刪除,因此不會出現任何矛盾。
實現

package ti9;

import java.util.Stack;

public class TwoStackImplQueue {
	 
	Stack<Integer> stack1 = new Stack<Integer>();
	Stack<Integer> stack2 = new Stack<Integer>();
	
	/*
	 * 佇列的資料壓入過程
	 */
	public void push(Integer element){
		stack1.push(element);
	}
	
	/*
	 * 佇列的資料彈出過程
	 */
	public Integer pop(){
		if(stack2.size() <= 0){	//第二個棧為空
			while(stack1.size() > 0){	//第一個棧不為空
				stack2.push(stack1.pop());	//將其第一個棧的資料壓入第二個棧中
			}
		}
		if(stack2.isEmpty()){
			try{
				throw new Exception("queue is empty");
			}catch(Exception e){
				//e.printStackTrace();
			}
		}
		Integer head = stack2.pop();
		return head;
	}
	
	public static void main(String[] args) {
		TwoStackImplQueue sq = new TwoStackImplQueue();
		sq.push(1);
		sq.push(3);
		sq.push(5);
		sq.push(4);
		sq.push(2);
		
		System.out.println(sq.pop());
		System.out.println(sq.pop());
		
		sq.push(7);
		System.out.println(sq.pop());
	}
}

【相關題目:用兩個佇列實現一個棧】
【題目】
通過一系列棧的壓入和彈出操作來分析用兩個佇列模擬一個棧的過程。
分析
(1)先往棧內壓入一個元素a:把a插入到兩個佇列任意一個,如插入queue1中。
(2)往棧內壓入b和c:把它們都插入到queue1中。
此時queue1中 有{a,b,c} a位於佇列的頭部,c位於佇列的尾部。
考慮棧的先入先出原則,最後被壓入棧的c應該最先被彈出。c位於queue1的尾部,只能 從佇列頭部刪除元素。
(3)從queue1中依次刪除a,b並插入queue2。
(4)再從queue1中刪除元素c。
相當於從棧中彈出元素c
如圖
在這裡插入圖片描述

實現

package ti9;

import java.util.ArrayDeque;
import java.util.Queue;

public class TwoQueueImplStack {
	Queue<Integer> queue1 = new ArrayDeque<Integer>();
	Queue<Integer> queue2 = new ArrayDeque<Integer>();
	
	/*
	 * 向棧中壓入資料
	 */
	public void push(Integer element){
		//兩個佇列都為空時,優先考慮 queue1
		if(queue1.isEmpty() && queue2.isEmpty()){
			queue1.add(element);
			return;
		}
		
		//如果queue1為空,queue2有資料,直接放入queue2
		if(queue1.isEmpty()){
			queue2.add(element);
			return;
		}
		
		//如果queue2為空,queue1有資料,直接放入queue1中
		if(queue2.isEmpty()){
			queue1.add(element);
			return;
		}
	}
	
	/*
	 * 從棧中彈出一個數據
	 */
	public Integer pop(){
		//如果兩個棧都為空,則沒有元素可以彈出,異常
		if(queue1.isEmpty() && queue2.isEmpty()){
			try{
				throw new Exception("satck is empty!");
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		
		//如果queue1中沒有元素,queue2中有元素,將其queue2中的元素依次放入queue1中,直到最後一個元素,彈出即可
		if(queue1.isEmpty()){
			while(queue2.size() > 1){
				queue1.add(queue2.poll());
			}
			return queue2.poll();
		}
		
		//如果queue2中沒有元素,queue1中有元素,將其queue1中的元素依次放入queue2中,直到最後一個元素,彈出即可
		if(queue2.isEmpty()){
			while(queue1.size() > 1){
				queue2.add(queue1.poll());
			}
			return queue1.poll();
		}
		
		return (Integer)null;
	}
	
	public static void main(String[] args) {
		TwoQueueImplStack qs = new TwoQueueImplStack();
		qs.push(2);
		qs.push(4);
		qs.push(7);
		qs.push(5);
		System.out.println(qs.pop());
		System.out.println(qs.pop());
		
		qs.push(1);
		System.out.println(qs.pop());
	}
}

參考:
1.《劍指offer》
2.https://blog.csdn.net/super_yc/article/details/75208174