棧(stack)
- 從數(shù)據(jù)結(jié)構(gòu)的角度理解:是一組數(shù)據(jù)的存放方式,特點為LIFO沮榜,即后進(jìn)先出(Last in, first out)坎吻。在這種數(shù)據(jù)結(jié)構(gòu)中,數(shù)據(jù)像積木那樣一層層堆起來晓铆,后面加入的數(shù)據(jù)就放在最上層。使用的時候绰播,最上層的數(shù)據(jù)第一個被用掉骄噪,這就叫做"后進(jìn)先出"。
- 從代碼運行方式角度理解:是調(diào)用棧蠢箩,表示函數(shù)或子例程像堆積木一樣存放腰池,以實現(xiàn)層層調(diào)用尾组。程序運行的時候,總是先完成最上層的調(diào)用示弓,然后將它的值返回到下一層調(diào)用讳侨,直至完成整個調(diào)用棧,返回最后的結(jié)果奏属。
- 從內(nèi)存區(qū)域的角度上理解:是存放數(shù)據(jù)的一種內(nèi)存區(qū)域跨跨。程序運行的時候,需要內(nèi)存空間存放數(shù)據(jù)囱皿。一般來說勇婴,系統(tǒng)會劃分出兩種不同的內(nèi)存空間:一種叫做
stack(棧)
,另一種叫做heap(堆)
嘱腥。
參考鏈接:Stack的三種含義
(圖片均來源于網(wǎng)絡(luò))
本文所述是站在數(shù)據(jù)結(jié)構(gòu)的角度耕渴。
棧可以通過鏈表和數(shù)組實現(xiàn)齿兔,先看通過數(shù)組實現(xiàn)的方式橱脸。
可以通過查看Stack
源碼學(xué)習(xí)
可以看到Stack
是Vector
的子類,Vector
本身是一個可增長的線程安全的對象數(shù)組( a growable array of objects)
里面主要是如下方法
E push(E item)
把項壓入堆棧頂部分苇。
E pop()
移除堆棧頂部的對象添诉,并作為此函數(shù)的值返回該對象。
E peek()
查看堆棧頂部的對象医寿,但不從堆棧中移除它栏赴。
boolean empty()
測試堆棧是否為空。
int search(Object o)
返回對象在堆棧中的位置靖秩,以 1 為基數(shù)须眷。
push
/**
* Pushes an item onto the top of this stack. This has exactly
* the same effect as:
* <blockquote><pre>
* addElement(item)</pre></blockquote>
*
* @param item the item to be pushed onto this stack.
* @return the <code>item</code> argument.
* @see java.util.Vector#addElement
*/
public E push(E item) {
addElement(item);
return item;
}
就是調(diào)用了Vector
的addElement
/**
* Adds the specified component to the end of this vector,
* increasing its size by one. The capacity of this vector is
* increased if its size becomes greater than its capacity.
*
* <p>This method is identical in functionality to the
* {@link #add(Object) add(E)}
* method (which is part of the {@link List} interface).
*
* @param obj the component to be added
*/
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
/**
* This implements the unsynchronized semantics of ensureCapacity.
* Synchronized methods in this class can internally call this
* method for ensuring capacity without incurring the cost of an
* extra synchronization.
*
* @see #ensureCapacity(int)
*/
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
就是判斷是否擴(kuò)容,然后賦值即可
pop
和peek
/**
* Removes the object at the top of this stack and returns that
* object as the value of this function.
*
* @return The object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
/**
* Looks at the object at the top of this stack without removing it
* from the stack.
*
* @return the object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
Vector
中
/**
* Deletes the component at the specified index. Each component in
* this vector with an index greater or equal to the specified
* {@code index} is shifted downward to have an index one
* smaller than the value it had previously. The size of this vector
* is decreased by {@code 1}.
*
* <p>The index must be a value greater than or equal to {@code 0}
* and less than the current size of the vector.
*
* <p>This method is identical in functionality to the {@link #remove(int)}
* method (which is part of the {@link List} interface). Note that the
* {@code remove} method returns the old value that was stored at the
* specified position.
*
* @param index the index of the object to remove
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
/**
* Returns the component at the specified index.
*
* <p>This method is identical in functionality to the {@link #get(int)}
* method (which is part of the {@link List} interface).
*
* @param index an index into this vector
* @return the component at the specified index
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
先調(diào)用peek()
得到需要出棧的對象沟突,也就是數(shù)組頂部的對象柒爸,在調(diào)用Vector
的removeElementAt
移除。
empty
/**
* Tests if this stack is empty.
*
* @return <code>true</code> if and only if this stack contains
* no items; <code>false</code> otherwise.
*/
public boolean empty() {
return size() == 0;
}
search
/**
* Returns the 1-based position where an object is on this stack.
* If the object <tt>o</tt> occurs as an item in this stack, this
* method returns the distance from the top of the stack of the
* occurrence nearest the top of the stack; the topmost item on the
* stack is considered to be at distance <tt>1</tt>. The <tt>equals</tt>
* method is used to compare <tt>o</tt> to the
* items in this stack.
*
* @param o the desired object.
* @return the 1-based position from the top of the stack where
* the object is located; the return value <code>-1</code>
* indicates that the object is not on the stack.
*/
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
參考鏈接:
java.util.Stack類簡介
接下來看看使用鏈?zhǔn)降姆绞綄崿F(xiàn)
鏈?zhǔn)浇Y(jié)構(gòu)
代碼表示:
private Node top = null;
private int number = 0;
class Node {
public T Item;
public Node Next;
}
入棧
入棧:將
top
的指向換為入棧的對象事扭,然后將這個入棧的對象指向上一個入棧的對象即可。
代碼表示:
public void push(T node) {
Node oldFirst = top;
top = new Node();
top.Item = node;
top.Next = oldFirst;
number++;
}
出棧
出棧:根據(jù)出棧的對象得到
next
乐横,然后top
指向即可求橄。代碼表示:
public T pop() {
T item = top.Item;
top = top.Next;
number--;
return item;
}
一個偽代碼類表示:
/**
* Created by zzw on 2017/6/27.
* Version:
* Des:
*/
public class StackLinkedList<T> {
private Node top = null;
private int number = 0;
class Node {
public T Item;
public Node Next;
}
public void push(T node) {
Node oldFirst = top;
top = new Node();
top.Item = node;
top.Next = oldFirst;
number++;
}
public T pop() {
T item = top.Item;
top = top.Next;
number--;
return item;
}
}
參考連接:
淺談算法和數(shù)據(jù)結(jié)構(gòu): 一 棧和隊列
水平有限,文中有什么不對或者有什么建議希望大家能夠指出葡公,謝謝罐农!