一、棧的介紹
棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱爲棧頂,相對地,把另一端稱爲棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成爲新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成爲新的棧頂元素。
棧的特點:先進後出
二、棧的簡單操作
1、棧的定義
/**
* 棧的接口
* @author hoaven
* @see Stack
* @see SetOfStacks
* @see StackWithMin
*/
public interface IStack<T> {
/**
* 入棧操作
* @param item
*/
void push(T item);
/**
* 出棧操作
* @return
*/
T pop();
/**
* 返回棧頂元素,但不出棧
* @return
*/
T peek();
/**
* 棧是否爲空
* @return boolean
*/
boolean isEmpty();
}
2、棧的基本實現
/**
* 棧的實現
*
* @author hoaven
* @see IStack
* @see Node 結點元素,具體定義請見鏈表的實現博客
*/
public class Stack<T> implements IStack<T> {
//棧頂
Node<T> top;
public T pop() {
if (top != null) {
T item = top.data;
//棧頂下移
top = top.next;
return item;
}
return null;
}
public void push(T item) {
Node<T> t = new Node<T>(item);
//新棧頂的next域指向舊棧頂
t.next = top;
top = t;
}
public T peek() {
if (top != null) {
return top.data;
}
return null;
}
public boolean isEmpty() {
return (top == null);
}
}
//單元測試
@Test
public void testStack(){
stack = new Stack<Integer>();
stack.push(1);
stack.push(2);
Assert.assertEquals(Integer.valueOf(2), stack.peek());
Assert.assertEquals(Integer.valueOf(2), stack.pop());
stack.push(3);
Assert.assertEquals(Integer.valueOf(3), stack.pop());
Assert.assertFalse(stack.isEmpty());
Assert.assertEquals(Integer.valueOf(1), stack.pop());
Assert.assertEquals(null, stack.peek());
Assert.assertEquals(null, stack.pop());
Assert.assertTrue(stack.isEmpty());
}
三、其他棧的實現
1、記錄棧的最大存儲容量和棧中內容實際索引值
/**
* 記錄棧的最大存儲容量和棧中內容實際索引值
*
* @author hoaven
*/
public class StackCapacity<T> extends Stack<T> {
private int capacity;
private int index = 0;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
//構造棧時指定棧的最大容量
public StackCapacity(int capacity) {
this.capacity = capacity;
}
public void push(T data) {
if (index >= capacity) {
throw new RuntimeException("棧容量不足");
}
super.push(data);
index++;
}
public T pop() {
index--;
return super.pop();
}
public boolean isFull() {
return (index == capacity);
}
}
2、一個能隨時獲取棧中最小值的棧
/**
* 一個能隨時獲取棧中最小值的棧的實現
* 實際上有兩個棧,第一個棧記錄所有的元素,第二個棧stackMin記錄每次入棧後當前棧中的最小值
*
* @author hoaven
* @see IStack
* @see Node
*/
public class StackWithMin extends Stack<Integer> {
Stack<Integer> stackMin;
public StackWithMin() {
stackMin = new Stack<Integer>();
}
public void push(Integer item) {
if (item <= min()) {
//item爲當前棧中的最小值
stackMin.push(item);
}
//第一個棧也要入棧
super.push(item);
}
public Integer pop() {
int value = super.pop();
if (value == min()) {
//出棧後,stackMin的棧頂就是第一個棧中剩餘元素的最小值
stackMin.pop();
}
return value;
}
/**
* 取得棧中的最小值
*
* @return
*/
public Integer min() {
if (stackMin.isEmpty()) {
return Integer.MAX_VALUE;
} else {
return stackMin.peek();
}
}
}
//測試
@Test
public void testStackWithMin(){
StackWithMin s = new StackWithMin();
s.push(4);
s.push(2);
Assert.assertEquals(Integer.valueOf(2), s.min());
s.push(3);
Assert.assertEquals(Integer.valueOf(2), s.min());
s.push(1);
Assert.assertEquals(Integer.valueOf(1), s.min());
Assert.assertEquals(Integer.valueOf(1), s.peek());
Assert.assertEquals(Integer.valueOf(1), s.pop());
Assert.assertEquals(Integer.valueOf(2), s.min());
}