1. 程式人生 > 實用技巧 >棧(Stack)

棧(Stack)

棧(Stack)

棧(Stack)是一種後進先出的資料結構(LIFO:last in first out),只允許訪問棧中的第一個資料項:即最後插入的資料項。移除這個資料項之後,才能看到第二個資料項,以此類推。

往棧中存入資料稱之為壓棧(push),移除資料稱之為彈棧(pop),此外通常還提供檢視棧頂元素的peek方法,此方法可以可以棧頂元素的值,但是並不會將其移除

java.util.Stack就是JDK提供的一種對棧的實現,這個實現是基於陣列的,由於棧非常簡單,我們沒有必須要分析原始碼,直接按照以下方法提供一個相同的自己的實現,此外,我們也可以基於連結串列來實現一個棧

基於陣列的棧的實現

關於基於陣列的棧的實現,只有一點值得注意的地方,其是LIFO,但是我們在使用陣列的時候,並不需要每次都將元素插入陣列的第一個位置,然後將之前的所有元素後移一個位置,只要用一個變數記住最後一個新增的元素的位置即可,當彈棧時,直接返回這個位置上的數字即可

  1. publicclassSimpleArrayStack<T>{
  2. privateObject[]array=null;
  3. privateintsize=0;
  4. privatestaticfinalintDEFAULR_INITIAL_SIZE=10;
  5. privateintcapacity=0;
  6. publicSimpleArrayStack(){
  7. this(DEFAULR_INITIAL_SIZE);
  8. }
  9. publicSimpleArrayStack(intinitial_size){
  10. super();
  11. this.capacity=initial_size;
  12. array=newObject[initial_size];
  13. }
  14. @SuppressWarnings("unchecked")
  15. publicTpop(){
  16. if(size<1){
  17. thrownewIllegalStateException("nomoreelements");
  18. }
  19. Tresult=(T)array[--size];
  20. array[size]=null;
  21. returnresult;
  22. }
  23. @SuppressWarnings("unchecked")
  24. publicTpeek(){
  25. if(size<1){
  26. thrownewIllegalStateException("nomoreelements");
  27. }
  28. return(T)array[size-1];
  29. }
  30. publicvoidpush(Te){
  31. intindex=size++;
  32. if(index>capacity){//擴容
  33. intnew_capacity=capacity+capacity>>1;
  34. if(new_capacity<=0){
  35. new_capacity=Integer.MAX_VALUE;
  36. }
  37. array=Arrays.copyOf(array,new_capacity);
  38. }
  39. array[index]=e;
  40. }
  41. publicintgetSize(){
  42. returnsize;
  43. }
  44. }

測試程式碼

  1. publicclassSimpleArrayStackTest{
  2. publicstaticvoidmain(String[]args){
  3. SimpleArrayStack<Integer>simpleStack=newSimpleArrayStack<Integer>();
  4. System.out.print("push:\t");
  5. for(inti=0;i<10;i++){
  6. simpleStack.push(i);
  7. System.out.print(i+"\t");
  8. }
  9. System.out.print("\npop:\t");
  10. while(simpleStack.getSize()>0){
  11. System.out.print(simpleStack.pop()+"\t");
  12. }
  13. }
  14. }

執行程式輸出

push: 0 1 2 3 4 5 6 7 8 9

pop: 9 8 7 6 5 4 3 2 1 0

可以看到資料都是按照和插入順序相反的方式彈出來了

基於連結串列的棧的實現

基於連結串列的Stack尤為簡單,我們可以使用上一節編寫SingleLinkList來實現,實際上就是一種委派,並把我們不想提供的方法給遮蔽,這可能沒有什麼技術含量,但是讀者意識到了,一個數據結構可以在另外一個數據結構的基礎上編寫

  1. publicclassSimpleLinkedListStack<T>{
  2. privateSingleLinkList<T>singleLinkList=newSingleLinkList<T>();
  3. publicvoidpush(Tt){
  4. singleLinkList.addFirst(t);
  5. }
  6. publicTpop(){
  7. returnsingleLinkList.removeFisrt();
  8. }
  9. publicTpeek(){
  10. returnsingleLinkList.getFirst();
  11. }
  12. publicintgetSize(){
  13. returnsingleLinkList.size();
  14. }
  15. }