Java資料結構漫談-Stack,java漫談-stack

來源:互聯網
上載者:User

Java資料結構漫談-Stack,java漫談-stack

Stack(棧)是一種比較典型的資料結構,其元素滿足後進先出(LIFO)的特點。

Java中Stack的實現繼承自Vector,所以其天然的具有了一些Vector的特點,所以棧也是安全執行緒的。

class Stack<E> extends Vector<E> {

事實上,除了繼承自Vector的那些方法之外,Stack只提供了5個方法:

    public E push(E item) {        addElement(item);        return item;    }    public synchronized E pop() {        E       obj;        int     len = size();        obj = peek();        removeElementAt(len - 1);        return obj;    }    public synchronized E peek() {        int     len = size();        if (len == 0)            throw new EmptyStackException();        return elementAt(len - 1);    }    public boolean empty() {        return size() == 0;    }    public synchronized int search(Object o) {        int i = lastIndexOf(o);        if (i >= 0) {            return size() - i;        }        return -1;    }

push函數是用來向Stack的頂部壓入一個元素,影響其效能的是 addElement的效能:

    public synchronized void addElement(E obj) {        modCount++;        ensureCapacityHelper(elementCount + 1);        elementData[elementCount++] = obj;    }

可以看出,其方法是在Vector的最後加入一個元素,其時間複雜度是o(1)。

peek函數是從查看棧頂元素,但是不刪除。其效能主要是由Vector的elementAt函數決定的:

    public synchronized E elementAt(int index) {        if (index >= elementCount) {            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);        }        return elementData(index);    }    E elementData(int index) {        return (E) elementData[index];    }

由於Vector的底層是數組實現的,通過下標可以直接進行定位,所以peek的時間複雜度也是o(1)。

pop函數是移除並擷取到棧頂元素,在源碼中可以看到,這裡調用peek擷取了棧頂元素,使用removeElementAt來刪除棧頂元素,這個函數也正是決定pop效能的關鍵:

    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 */    }

咋一看來,這裡刪除一個元素之後,都會對數組中的元素進行複製調整,時間複雜度是o(n),但是考慮到傳進來的index值的特殊性:

index = elementCount -1;

這樣的話if(j>0)的條件永遠都不會成立,因為j永遠都是0,中間複製調整元素的操作就避免了,僅僅是在最後把Vector最後的值賦值為null,時間複雜度是o(1)。

search是尋找一個元素在Stack中的index,這裡起作用的是Vector的lastIndexOf函數,代碼如下:

    public synchronized int lastIndexOf(Object o) {        return lastIndexOf(o, elementCount-1);    }    public synchronized int lastIndexOf(Object o, int index) {        if (index >= elementCount)            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);        if (o == null) {            for (int i = index; i >= 0; i--)                if (elementData[i]==null)                    return i;        } else {            for (int i = index; i >= 0; i--)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }

可以看出,尋找的過程是從後向前,挨個比較,其時間複雜度必然是o(n)。

 

Stack是Vector的子類,所以Vector的函數這裡也適用,這裡不再贅述,在Vector相關的介紹文章中會有。

Stack是安全執行緒的,所以其效能必然受到影響,如果需要使用一個非安全執行緒的Stack,可以直接使用LinkedList,LinkedList本身提供的方法就包含了Stack的操作。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.