棧(Stack)
阿新 • • 發佈:2020-09-15
棧(Stack)
棧(Stack)是一種後進先出的資料結構(LIFO:last in first out),只允許訪問棧中的第一個資料項:即最後插入的資料項。移除這個資料項之後,才能看到第二個資料項,以此類推。
往棧中存入資料稱之為壓棧(push
),移除資料稱之為彈棧(pop
),此外通常還提供檢視棧頂元素的peek
方法,此方法可以可以棧頂元素的值,但是並不會將其移除
java.util.Stack
就是JDK提供的一種對棧的實現,這個實現是基於陣列的,由於棧非常簡單,我們沒有必須要分析原始碼,直接按照以下方法提供一個相同的自己的實現,此外,我們也可以基於連結串列來實現一個棧
基於陣列的棧的實現
關於基於陣列的棧的實現,只有一點值得注意的地方,其是LIFO,但是我們在使用陣列的時候,並不需要每次都將元素插入陣列的第一個位置,然後將之前的所有元素後移一個位置,只要用一個變數記住最後一個新增的元素的位置即可,當彈棧時,直接返回這個位置上的數字即可
- publicclassSimpleArrayStack<T>{
- privateObject[]array=null;
- privateintsize=0;
- privatestaticfinalintDEFAULR_INITIAL_SIZE=10;
- privateintcapacity=0;
- publicSimpleArrayStack(){
- this(DEFAULR_INITIAL_SIZE);
- }
- publicSimpleArrayStack(intinitial_size){
- super();
- this.capacity=initial_size;
- array=newObject[initial_size];
- }
- @SuppressWarnings("unchecked")
- publicTpop(){
- if(size<1){
- thrownewIllegalStateException("nomoreelements");
- }
- Tresult=(T)array[--size];
- array[size]=null;
- returnresult;
- }
- @SuppressWarnings("unchecked")
- publicTpeek(){
- if(size<1){
- thrownewIllegalStateException("nomoreelements");
- }
- return(T)array[size-1];
- }
- publicvoidpush(Te){
- intindex=size++;
- if(index>capacity){//擴容
- intnew_capacity=capacity+capacity>>1;
- if(new_capacity<=0){
- new_capacity=Integer.MAX_VALUE;
- }
- array=Arrays.copyOf(array,new_capacity);
- }
- array[index]=e;
- }
- publicintgetSize(){
- returnsize;
- }
- }
測試程式碼
- publicclassSimpleArrayStackTest{
- publicstaticvoidmain(String[]args){
- SimpleArrayStack<Integer>simpleStack=newSimpleArrayStack<Integer>();
- System.out.print("push:\t");
- for(inti=0;i<10;i++){
- simpleStack.push(i);
- System.out.print(i+"\t");
- }
- System.out.print("\npop:\t");
- while(simpleStack.getSize()>0){
- System.out.print(simpleStack.pop()+"\t");
- }
- }
- }
執行程式輸出
push: 0 1 2 3 4 5 6 7 8 9 pop: 9 8 7 6 5 4 3 2 1 0 |
可以看到資料都是按照和插入順序相反的方式彈出來了
基於連結串列的棧的實現
基於連結串列的Stack尤為簡單,我們可以使用上一節編寫SingleLinkList
來實現,實際上就是一種委派,並把我們不想提供的方法給遮蔽,這可能沒有什麼技術含量,但是讀者意識到了,一個數據結構可以在另外一個數據結構的基礎上編寫
- publicclassSimpleLinkedListStack<T>{
- privateSingleLinkList<T>singleLinkList=newSingleLinkList<T>();
- publicvoidpush(Tt){
- singleLinkList.addFirst(t);
- }
- publicTpop(){
- returnsingleLinkList.removeFisrt();
- }
- publicTpeek(){
- returnsingleLinkList.getFirst();
- }
- publicintgetSize(){
- returnsingleLinkList.size();
- }
- }