數據結構筆記--棧的總結及java數組實現簡單棧結構


雜談"棧"結構:  

  棧(Stack)是一種插入刪除操作都只能在一個位置上進表,這個位置位於表的末端,叫做棧頂(Top).

  對棧的基本操作有push和pop,表示進棧和出棧.也就相當於插入和刪除操作.

  棧結構又叫做LIFO(后進先出)表.歸根結底是一個表結構,因此任何能夠實現表結構的方法都能實現棧.

  在java語言中,ArrayList和LinkedList都支持棧操作,棧操作都是常數時間的操作,棧的實現方式一般有兩種,一種是使用順序存儲的方式,即使用數組來實現,用ArrayList可以輕易實現棧結構,也可以自己使用數組來實現,一會下面我就用數組來實現棧,第二種是使用鏈式存儲實現,即可以使用LinkedList來實現.

使用數組實現順序棧:

  使用arrayList和linkedList實現棧比較簡單,畢竟本身他們就是封裝好的功能,接下來我用數組來實現一個棧結構:

MyStack:

package com.wang.list; import java.util.Arrays; public class MyStack<T> { //使用數組實現這個棧結構
    private T[] dataArr; //當前元素的個數
    private int theSize; //棧的容量
    private static final int DEFAULT_CAPACITY=10; public MyStack(){ clear(); } //初始化數組,默認大小10,元素個數theSize初始化為o
    private void clear(){ theSize=0; ensureCapacity(DEFAULT_CAPACITY); } //棧元素容量
    public int size(){ return theSize; } private void ensureCapacity(int newCapacity){ if(newCapacity<theSize){ return; } T[] oldArr=dataArr; dataArr=(T[])new Object[newCapacity]; for(int i=0;i<size();i++){ dataArr[i]=oldArr[i]; } } //入棧
    public void push(T value){ if(dataArr.length==size()){ ensureCapacity(size()*2); } dataArr[theSize++]=value; } //棧是否為空
    public boolean isEmpty(){ return size()==0; } //出棧
    public T pop(){ if(isEmpty()){ return null; } T theValue=dataArr[theSize-1]; dataArr[--theSize]=null; return theValue; } //返回棧尾元素
    public T peek(){ if(isEmpty()){ return null; } T theValue=dataArr[theSize-1]; return theValue; } }

使用Node()輔助類實現鏈式棧:

 

package com.wang.list;

public class MyStack1<T> {

    
    private class Node{
        
         T data;
        Node next;
        
        
        public Node(T data,Node next){
            
            this.data=data;
            this.next=next;
        }
    }
    
    //保存元素個數
    private int theSize;
    
    //保存棧頂元素
    private Node top;
    
    public MyStack1(){
        top=null;
    }
    
    public MyStack1(T value){
        top=new Node(value,null);
    }
    
    public void push(T value){
        top=new Node(value,top);
        theSize++;
        
    }
    
    public T pop(){
        Node old=top;
        top=top.next;
        old.next=null;
        theSize--;
        return old.data;
        
    }
    
    public T peek(){
        return top.data;
        
    }
    public int size(){
        return theSize;
    }
    
    public boolean isEmpty(){
        return size()==0;
    }
}

 

 

 

棧的應用:

  進制轉換:

    比如將十進制下的某個數轉換為二進制中的某個數,則可以對該數進行除2取余操作,然后將余數壓棧,之后再將所有的數出棧,即是所對應的二進制數,這其實是棧對於逆序操作的一個實例.

  平衡符號:

    檢查那些成對出現的符號是否匹配,比如(),[],{}等

    實現過程大概如下:

      做一個空棧,讀入字符直到文件末尾.如果字符是一個開放符號(比如"{}"中的"{"),則將其推入棧中.如果字符是一個封閉符號(比如"{}"中的"}"),則判斷棧是否為空,為空則報錯.不為空,則將棧頂元素彈出,判斷彈出元素是否是其對應的開放符號,不是則報錯,在文件結尾,如果棧非空,就報錯.

  后綴表達式:

    不知道何為后綴表達式,請自行百度,后綴表達式的記法又稱為逆波蘭式,它的求值過程恰好就是從左到右的過程,可以使用一個棧,當見到一個數時就入棧,當遇到一個一個運算符時,就從棧中彈出兩個數進行計算,再將所得結果入棧.最后的到的數就是計算結果.

  用於方法調用:

    存在方法調用時,比如在一個方法中調用了另一個方法,這時候需要把當前方法一些重要信息記錄並保存下來,保存到一個棧中,然后再跳到新方法中去執行,當方法返回的時候,去查看棧頂的那個保存信息(棧幀),然后進行復原,事實上這是在計算機系統中一個非常重要的應用,上面的全部工作都可以用一個棧來實現.事實上,在實現遞歸的每一種程序語言都是這么干的,所存儲的信息叫做活動記錄,或者說棧幀.這個細說,比較復雜,想深入了解,自己百度吧.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM