數據結構-棧 學習筆記
棧結構:線性結構。從數據的存儲結構來進一步劃分,棧結構包括兩類:
順序棧結構:使用一組地址連續的內存單元依次保存棧中的數據;
鏈式棧結構:使用鏈表形式保存棧中各元素的值;
在棧結構中只能在一端進行操作,該操作端稱爲棧頂,另一端稱爲棧底。保存和取出數據都只能從棧結構的一端進行。
棧結構是按照"後進先出"的原則處理結點數據的。
圖1
Java實現的棧:
/**
* 棧: 先進後出,後進先出 的線性表(LIFO). 限定僅在表尾進行插入和刪除操作的線性表.
*
* @see java.util.ArrayDeque
*/
public class xStack<E> {
Object[] elements;
int bottom; // 棧底. index=0
int top; // 棧頂.進行插入,刪除等操作.
private static final int DEFAULT_INITIAL_CAPACITY = 1 << 3;
private static final int MAX_CAPACITY = 1 << 16;
/**
* 構造
*/
public xStack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
/**
* 構造
*
* @param c
*/
public xStack(Collection<? extends E> c) {
elements = new Object[calculateSize(c.size())];
addAll(c);
}
/* 計算stack大小 */
private int calculateSize(int capacity) {
if (capacity < DEFAULT_INITIAL_CAPACITY)
return DEFAULT_INITIAL_CAPACITY;
return Math.min((int) Math.pow(2, capacity >> 2), MAX_CAPACITY);
}
/**
* 壓入若干個元素
*
* @param c
* @return
*/
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
/**
* 壓入一個元素
*
* @param e
* @return
*/
public boolean add(E e) {
Objects.requireNonNull(e);
int length = elements.length - 1;
if (top < length) {
elements[top] = e;
top++;
} else if (top == length) {
doubleCapacity(); // 擴容
elements[top] = e;
top++;
}
return true;
}
/* 擴容 */
private void doubleCapacity() {
int blank = elements.length;
int newCapacity = Math.min(blank << 1, MAX_CAPACITY);
if (newCapacity < 0)
throw new IllegalStateException("xStack too big");
Object[] o = new Object[newCapacity];
System.arraycopy(elements, 0, o, 0, blank);
elements = o;
}
/**
* 測試棧是否爲空
*/
public boolean isEmpty() {
return bottom == top;
}
/**
* 查看棧頂,但不移除. 允許返回null
*/
@SuppressWarnings("unchecked")
public E getTop() {
return (E) elements[top - 1];
}
/**
* 從棧頂彈出一個元素(top).
*/
public E pop() {
int h = top;
@SuppressWarnings("unchecked")
E result = (E) elements[h - 1];
if (result == null)
return null;
elements[h - 1] = null;
Object[] o = new Object[elements.length];
System.arraycopy(elements, 0, o, 0, h);
elements = o;
top--;
return result;
}
/**
* 將元素壓入棧頂(top).
*/
public void push(E e) {
Objects.requireNonNull(e);
int length = elements.length - 1;
if (top < length) {
elements[top] = e;
top++;
} else if (top == length) {
doubleCapacity(); // 擴容
elements[top] = e;
top++;
}
}
/**
* 返回元素在棧中的位置
*/
public int search(Object o) {
if (o == null)
return -1;
int mask = elements.length - 1;
Object obj = null;
int i = bottom;
while ((obj = elements[i]) != null) {
if (o.equals(obj))
return i;
i = (i + 1) & mask;
}
return -1;
}
/**
* 返回棧的深度
*/
public int deep() {
return (top - bottom) & (elements.length - 1);
}
/**
* 返回stack對象的字符串表示
*/
public String toString() {
if (deep() == 0)
return "[]";
Object[] o = Arrays.copyOf(elements, deep());
return Arrays.toString(o);
}
}
注: