Java数据结构与算法:栈
原文出處:http://www.cnblogs.com/skywang12345/p/3562239.html
注意:本文所說的棧是數據結構中的棧,而不是內存模型中棧
1. 棧的介紹
棧(stack)是限定僅在表尾一端進行插入或刪除操作的特殊線性表。對于棧來說, 允許進行插入或刪除操作的一端稱為棧頂(top),而另一端稱為棧底(bottom)。不含元素棧稱為空棧,向棧中插入一個新元素稱為入棧或壓棧, 從棧中刪除一個元素稱為出棧或退棧。
假設有一個棧S=(a1, a2, …, an), a1先進棧, an最后進棧。稱a1為棧底元素, an為棧頂元素, 如圖3.1所示。出棧時只允許在棧頂進行, 所以an先出棧, a1最后出棧。因此又稱棧為后進先出(Last In First Out,LIFO)的線性表。
棧(stack),是一種線性存儲結構,它有以下幾個特點:
- 棧中數據是按照”后進先出(LIFO, Last In First Out)”方式進出棧的。
- 向棧中添加/刪除數據時,只能從棧頂進行操作。
棧通常包括的三種操作:push、peek、pop。
- push – 向棧中添加元素。
- peek – 返回棧頂元素。
- pop – 返回并刪除棧頂元素的操作。
1.1 棧的示意圖
棧中的數據依次是 30 –> 20 –> 10
1.2 出棧
出棧前:棧頂元素是30。此時,棧中的元素依次是 30 –> 20 –> 10
出棧后:30出棧之后,棧頂元素變成20。此時,棧中的元素依次是 20 –> 10
1.3 入棧
入棧前:棧頂元素是20。此時,棧中的元素依次是 20 –> 10
入棧后:40入棧之后,棧頂元素變成40。此時,棧中的元素依次是 40 –> 20 –> 10
2. 棧的Java實現
JDK包中也提供了”棧”的實現,它就是集合框架中的Stack類。本部分給出2種Java實現
2.1 Java實現一
數組實現的棧,能存儲任意類型的數據
/*** Java : 數組實現的棧,能存儲任意類型的數據*/ import java.lang.reflect.Array;public class GeneralArrayStack<T> {private static final int DEFAULT_SIZE = 12;private T[] mArray;private int count;public GeneralArrayStack(Class<T> type) {this(type, DEFAULT_SIZE);}public GeneralArrayStack(Class<T> type, int size) {// 不能直接使用mArray = new T[DEFAULT_SIZE];mArray = (T[]) Array.newInstance(type, size);count = 0;}// 將val添加到棧中public void push(T val) {mArray[count++] = val;}// 返回“棧頂元素值”public T peek() {return mArray[count-1];}// 返回“棧頂元素值”,并刪除“棧頂元素”public T pop() {T ret = mArray[count-1];count--;return ret;}// 返回“棧”的大小public int size() {return count;}// 返回“棧”是否為空public boolean isEmpty() {return size()==0;}// 打印“棧”public void PrintArrayStack() {if (isEmpty()) {System.out.printf("stack is Empty\n");}System.out.printf("stack size()=%d\n", size());int i=size()-1;while (i>=0) {System.out.println(mArray[i]);i--;}}public static void main(String[] args) {String tmp;GeneralArrayStack<String> astack = new GeneralArrayStack<String>(String.class);// 將10, 20, 30 依次推入棧中astack.push("10");astack.push("20");astack.push("30");// 將“棧頂元素”賦值給tmp,并刪除“棧頂元素”tmp = astack.pop();System.out.println("tmp="+tmp);// 只將“棧頂”賦值給tmp,不刪除該元素.tmp = astack.peek();System.out.println("tmp="+tmp);astack.push("40");astack.PrintArrayStack(); // 打印棧} }運行結果:
tmp=30 tmp=20 stack size()=3 40 20 10結果說明:GeneralArrayStack是通過數組實現的棧,而且GeneralArrayStack中使用到了泛型
2.2 Java實現二
Java的 Collection集合 中自帶的”棧”(stack)的示例
import java.util.Stack;/*** Java : java集合包中的Stack的演示程序*/ public class StackTest {public static void main(String[] args) {int tmp=0;Stack<Integer> astack = new Stack<Integer>();// 將10, 20, 30 依次推入棧中astack.push(10);astack.push(20);astack.push(30);// 將“棧頂元素”賦值給tmp,并刪除“棧頂元素”tmp = astack.pop();//System.out.printf("tmp=%d\n", tmp);// 只將“棧頂”賦值給tmp,不刪除該元素.tmp = (int)astack.peek();//System.out.printf("tmp=%d\n", tmp);astack.push(40);while(!astack.empty()) {tmp = (int)astack.pop();System.out.printf("tmp=%d\n", tmp);}} }運行結果:
tmp=40 tmp=20 tmp=103. Stack詳細介紹
學完Vector了之后,接下來我們開始學習Stack。Stack很簡單,它繼承于Vector。學習方式還是和之前一樣,先對Stack有個整體認識,然后再學習它的源碼;最后再通過實例來學會使用它。內容包括:
- 第1部分 Stack介紹
- 第2部分 Stack源碼解析(基于JDK1.6.0_45)
- 第3部分 Vector示例
3.1 Stack介紹
Stack是棧。它的特性是:先進后出(FILO, First In Last Out)。
java工具包中的Stack是繼承于Vector(矢量隊列)的,由于Vector是通過數組實現的,這就意味著,Stack也是通過數組實現的,而非鏈表。當然,我們也可以將LinkedList當作棧來使用!在“Java 集合系列06之 Vector詳細介紹(源碼解析)和使用示例”中,已經詳細介紹過Vector的數據結構,這里就不再對Stack的數據結構進行說明了。
3.2 Stack的繼承關系
java.lang.Object ? java.util.AbstractCollection<E>? java.util.AbstractList<E>? java.util.Vector<E>? java.util.Stack<E>public class Stack<E> extends Vector<E> {}Stack和Collection的關系如下圖
4. 棧
4.1 用LinkedList實現棧結構的集合
public class MyStack {private LinkedList link;public MyStack() {link = new LinkedList();}public void add(Object obj) {link.addFirst(obj);}public Object get() {// return link.getFirst();return link.removeFirst();}public boolean isEmpty() {return link.isEmpty();} }4.2 棧的實現
// stack.java // demonstrates stacks // to run this program: C>java StackApp class StackX{private int maxSize; // size of stack arrayprivate long[] stackArray;private int top; // top of stack //--------------------------------------------------------------public StackX(int s) // constructor{maxSize = s; // set array sizestackArray = new long[maxSize]; // create arraytop = -1; // no items yet} //--------------------------------------------------------------public void push(long j) // put item on top of stack{stackArray[++top] = j; // increment top, insert item} //--------------------------------------------------------------public long pop() // take item from top of stack{return stackArray[top--]; // access item, decrement top} //--------------------------------------------------------------public long peek() // peek at top of stack{return stackArray[top];} //--------------------------------------------------------------public boolean isEmpty() // true if stack is empty{return (top == -1);} //--------------------------------------------------------------public boolean isFull() // true if stack is full{return (top == maxSize-1);} //--------------------------------------------------------------} // end class StackX class StackApp{public static void main(String[] args){StackX theStack = new StackX(10); // make new stacktheStack.push(20); // push items onto stacktheStack.push(40);theStack.push(60);theStack.push(80);while( !theStack.isEmpty() ) // until it's empty,{ // delete item from stacklong value = theStack.pop();System.out.print(value); // display itSystem.out.print(" ");} // end whileSystem.out.println("");} // end main()} // end class StackApp4.3 棧實例1:單詞逆序
// reverse.java // stack used to reverse a string // to run this program: C>java ReverseApp import java.io.*; // for I/O class StackX{private int maxSize;private char[] stackArray;private int top; //--------------------------------------------------------------public StackX(int max) // constructor{maxSize = max;stackArray = new char[maxSize];top = -1;} //--------------------------------------------------------------public void push(char j) // put item on top of stack{stackArray[++top] = j;} //--------------------------------------------------------------public char pop() // take item from top of stack{return stackArray[top--];} //--------------------------------------------------------------public char peek() // peek at top of stack{return stackArray[top];} //--------------------------------------------------------------public boolean isEmpty() // true if stack is empty{return (top == -1);} //--------------------------------------------------------------} // end class StackX class Reverser{private String input; // input stringprivate String output; // output string //--------------------------------------------------------------public Reverser(String in) // constructor{ input = in; } //--------------------------------------------------------------public String doRev() // reverse the string{int stackSize = input.length(); // get max stack sizeStackX theStack = new StackX(stackSize); // make stackfor(int j=0; j<input.length(); j++){char ch = input.charAt(j); // get a char from inputtheStack.push(ch); // push it}output = "";while( !theStack.isEmpty() ){char ch = theStack.pop(); // pop a char,output = output + ch; // append to output}return output;} // end doRev() //--------------------------------------------------------------} // end class Reverser class ReverseApp{public static void main(String[] args) throws IOException{String input, output;while(true){System.out.print("Enter a string: ");System.out.flush();input = getString(); // read a string from kbdif( input.equals("") ) // quit if [Enter]break;// make a ReverserReverser theReverser = new Reverser(input);output = theReverser.doRev(); // use itSystem.out.println("Reversed: " + output);} // end while} // end main() //--------------------------------------------------------------public static String getString() throws IOException{InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);String s = br.readLine();return s;} //--------------------------------------------------------------} // end class ReverseApp4.4 棧實例2:分隔符匹配
// brackets.java // stacks used to check matching brackets // to run this program: C>java bracketsApp import java.io.*; // for I/O class StackX{private int maxSize;private char[] stackArray;private int top; //--------------------------------------------------------------public StackX(int s) // constructor{maxSize = s;stackArray = new char[maxSize];top = -1;} //--------------------------------------------------------------public void push(char j) // put item on top of stack{stackArray[++top] = j;} //--------------------------------------------------------------public char pop() // take item from top of stack{return stackArray[top--];} //--------------------------------------------------------------public char peek() // peek at top of stack{return stackArray[top];} //--------------------------------------------------------------public boolean isEmpty() // true if stack is empty{return (top == -1);} //--------------------------------------------------------------} // end class StackX class BracketChecker{private String input; // input string //--------------------------------------------------------------public BracketChecker(String in) // constructor{ input = in; } //--------------------------------------------------------------public void check(){int stackSize = input.length(); // get max stack sizeStackX theStack = new StackX(stackSize); // make stackfor(int j=0; j<input.length(); j++) // get chars in turn{char ch = input.charAt(j); // get charswitch(ch){case '{': // opening symbolscase '[':case '(':theStack.push(ch); // push thembreak;case '}': // closing symbolscase ']':case ')':if( !theStack.isEmpty() ) // if stack not empty,{char chx = theStack.pop(); // pop and checkif( (ch=='}' && chx!='{') ||(ch==']' && chx!='[') ||(ch==')' && chx!='(') )System.out.println("Error: "+ch+" at "+j);}else // prematurely emptySystem.out.println("Error: "+ch+" at "+j);break;default: // no action on other charactersbreak;} // end switch} // end for// at this point, all characters have been processedif( !theStack.isEmpty() )System.out.println("Error: missing right delimiter");} // end check() //--------------------------------------------------------------} // end class BracketChecker class BracketsApp{public static void main(String[] args) throws IOException{String input;while(true){System.out.print("Enter string containing delimiters: ");System.out.flush();input = getString(); // read a string from kbdif( input.equals("") ) // quit if [Enter]break;// make a BracketCheckerBracketChecker theChecker = new BracketChecker(input);theChecker.check(); // check brackets} // end while} // end main() //--------------------------------------------------------------public static String getString() throws IOException{InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);String s = br.readLine();return s;} //--------------------------------------------------------------} // end class BracketsApp4.5 棧的鏈表實現
// linkStack.java // demonstrates a stack implemented as a list // to run this program: C>java LinkStackApp class Link{public long dData; // data itempublic Link next; // next link in list // -------------------------------------------------------------public Link(long dd) // constructor{ dData = dd; } // -------------------------------------------------------------public void displayLink() // display ourself{ System.out.print(dData + " "); }} // end class Link class LinkList{private Link first; // ref to first item on list // -------------------------------------------------------------public LinkList() // constructor{ first = null; } // no items on list yet // -------------------------------------------------------------public boolean isEmpty() // true if list is empty{ return (first==null); } // -------------------------------------------------------------public void insertFirst(long dd) // insert at start of list{ // make new linkLink newLink = new Link(dd);newLink.next = first; // newLink --> old firstfirst = newLink; // first --> newLink} // -------------------------------------------------------------public long deleteFirst() // delete first item{ // (assumes list not empty)Link temp = first; // save reference to linkfirst = first.next; // delete it: first-->old nextreturn temp.dData; // return deleted link} // -------------------------------------------------------------public void displayList(){Link current = first; // start at beginning of listwhile(current != null) // until end of list,{current.displayLink(); // print datacurrent = current.next; // move to next link}System.out.println("");} // -------------------------------------------------------------} // end class LinkList class LinkStack{private LinkList theList; //--------------------------------------------------------------public LinkStack() // constructor{theList = new LinkList();} //--------------------------------------------------------------public void push(long j) // put item on top of stack{theList.insertFirst(j);} //--------------------------------------------------------------public long pop() // take item from top of stack{return theList.deleteFirst();} //--------------------------------------------------------------public boolean isEmpty() // true if stack is empty{return ( theList.isEmpty() );} //--------------------------------------------------------------public void displayStack(){System.out.print("Stack (top-->bottom): ");theList.displayList();} //--------------------------------------------------------------} // end class LinkStack class LinkStackApp{public static void main(String[] args){LinkStack theStack = new LinkStack(); // make stacktheStack.push(20); // push itemstheStack.push(40);theStack.displayStack(); // display stacktheStack.push(60); // push itemstheStack.push(80);theStack.displayStack(); // display stacktheStack.pop(); // pop itemstheStack.pop();theStack.displayStack(); // display stack} // end main()} // end class LinkStackApp總結
以上是生活随笔為你收集整理的Java数据结构与算法:栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java数据结构与算法:排序算法
- 下一篇: Java数据结构与算法:队列