本文首發於我的個人部落格:尾尾部落
0. 基礎概念
棧:後進先出(LIFO)
佇列:先進先出(FIFO)
1. 棧的 java 實現
import java.util.Arrays;
public class Stack {
private int size = 0; //棧頂位置
private int[] array;
public Stack(){
this(10);
}
public Stack(int init) {
if(init <= 0){
init = 10;
}
array = new int[init];
}
/**
* 入棧操作
* @param item 入棧的元素
*/
public void push(int item){
if(size == array.length){
array = Arrays.copyOf(array, size*2); //擴容操作
}
array[size++] = item;
}
/**
* 獲取棧頂元素,但棧頂元素不出棧
* @return 棧頂元素
*/
public int peek(){
if(size == 0){ //空棧
throw new IndexOutOfBoundsException("棧是空的");
}
return array[size-1];
}
/**
* 出棧,同時獲取棧頂元素
* @return
*/
public int pop(){
int item = peek(); //獲取棧頂元素
size--; //直接使元素個數減1,不用清除元素,下次入棧會覆蓋舊元素的值
return item;
}
/**
* 判斷棧是否已滿
* @return
*/
public boolean isFull(){
return size == array.length;
}
/**
* 判斷棧是否為空
* @return
*/
public boolean isEmpty(){
return size == 0;
}
public int getSize(){
return size;
}
}
複製程式碼
2. 佇列的 java 實現
public class ArrayQueue {
private final Object[] queue; //宣告一個陣列
private int head;
private int tail;
/**
* 初始化佇列
* @param capacity 佇列長度
*/
public ArrayQueue(int capacity){
this.queue = new Object[capacity];
}
/**
* 入隊
* @param o 入隊元素
* @return 入隊成功與否
*/
public boolean put(Object o){
if(head == (tail+1)%queue.length){
//說明隊滿
return false;
}
queue[tail] = o;
tail = (tail+1)%queue.length; //tail標記後移一位
return true;
}
/**
* 返回隊首元素,但不出隊
* @return
*/
public Object peak() {
if(head==tail){
//隊空
return null;
}
return queue[head];
}
/**
* 出隊
* @return 出隊元素
*/
public Object pull(){
if(head==tail){
return null;
}
Object item = queue[head];
queue[head] = null;
return item;
}
/**
* 判斷是否為空
* @return
*/
public boolean isEmpty(){
return head == tail;
}
/**
* 判斷是否為滿
* @return
*/
public boolean isFull(){
return head == (tail+1)%queue.length;
}
/**
* 獲取佇列中的元素個數
* @return
*/
public int getsize(){
if(tail>=head){
return tail-head;
}else{
return (tail+queue.length)-head;
}
}
}
複製程式碼
3. 用兩個棧實現佇列
劍指offer:用兩個棧實現佇列 LeetCode:Implement Queue using Stacks
class MyQueue {
Stack<Integer> input = new Stack<Integer>();
Stack<Integer> output = new Stack<Integer>();
/** Push element x to the back of queue. */
public void push(int x) {
input.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
peek();
return output.pop();
}
/** Get the front element. */
public int peek() {
if(output.isEmpty()){
while(!input.isEmpty())
output.push(input.pop());
}
return output.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return input.isEmpty() && output.isEmpty();
}
}
複製程式碼
4. 用佇列實現棧
LeetCode:Implement Stack using Queues
class MyStack {
Queue<Integer> q1 = new LinkedList<Integer>();
Queue<Integer> q2 = new LinkedList<Integer>();
/** Push element x onto stack. */
public void push(int x) {
if(q1.isEmpty()){
q1.add(x);
for(int i = 0; i < q2.size(); i++){
q1.add(q2.poll());
}
}else{
q2.add(x);
for(int i = 0; i < q1.size(); i++){
q2.add(q1.poll());
}
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return q1.isEmpty() ? q2.poll() : q1.poll();
}
/** Get the top element. */
public int top() {
return q1.isEmpty() ? q2.peek() : q1.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return q1.isEmpty() && q2.isEmpty();
}
}
複製程式碼
5. 包含min函式的棧
劍指offer:包含min函式的棧 定義棧的資料結構,請在該型別中實現一個能夠得到棧最小元素的min函式。
class MinStack {
Stack<Integer> stack = new Stack<Integer>();
Stack<Integer> temp = new Stack<Integer>();
public void push(int x) {
stack.push(x);
if(temp.isEmpty() || temp.peek() >= x)
temp.push(x);
}
public void pop() {
int x = stack.pop();
int min = temp.peek();
if(x == min)
temp.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return temp.peek();
}
}
複製程式碼
6. 棧的壓入、彈出序列
劍指offer:棧的壓入、彈出序列 輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否為該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public boolean IsPopOrder(int [] pushA, int [] popA) {
if(pushA.length != popA.length ||
pushA.length == 0 ||
popA.length == 0)
return false;
Stack<Integer> stack = new Stack<>();
int index = 0;
for(int i = 0; i < pushA.length; i++){
stack.push(pushA[i]);
while(!stack.empty() && stack.peek() == popA[index]){
stack.pop();
index++;
}
}
return stack.empty();
}
}
複製程式碼