一、棧的基本定義
棧是一種數據結構,它代表一種特殊的線性表,這種線性表只能在固定一端(通常認為是線性表的尾端)進行插入、刪除操作的特殊線性表,通常就是在線性表的尾端進行插入、刪除操作。
二、順序棧的實現
順序棧是利用一組地址連續的存儲單元依次存放從棧底到棧頂的數據元素,棧底位置固定不變,它的棧頂元素可以直接通過順序棧底層數組的數組元素arr[size - 1]來訪問。
1 package com.ietree.basic.datastructure.stack; 2 3 import java.util.Arrays; 4 5 /** 6 * 順序棧 7 * 8 * Created by ietree 9 * 2017/4/29 10 */ 11 public class SequenceStack<T> { 12 13 private int DEFAULT_SIZE = 10; 14 // 保存數組的長度 15 private int capacity; 16 // 定義當底層數組容量不夠時,程序每次增加的數組長度 17 private int capacityIncrement = 0; 18 // 定義一個數組用於保存順序棧的元素 19 private Object[] elementData; 20 // 保存順序棧中元素的當前個數 21 private int size = 0; 22 23 // 以默認數組長度創建空順序棧 24 public SequenceStack() { 25 26 capacity = DEFAULT_SIZE; 27 elementData = new Object[capacity]; 28 29 } 30 31 // 以一個初始化元素來創建順序棧 32 public SequenceStack(T element) { 33 34 this(); 35 elementData[0] = element; 36 size++; 37 38 } 39 40 /** 41 * 以指定長度的數組來創建順序線性表 42 * 43 * @param element 指定順序棧中第一個元素 44 * @param initSize 指定順序棧底層數組的長度 45 */ 46 public SequenceStack(T element, int initSize) { 47 48 this.capacity = initSize; 49 elementData = new Object[capacity]; 50 elementData[0] = element; 51 size++; 52 53 } 54 55 /** 56 * 以指定長度的數組來創建順序棧 57 * 58 * @param element 指定順序棧中第一個元素 59 * @param initSize 指定順序棧底層數組的長度 60 * @param capacityIncrement 指定當順序棧底層數組的長度不夠時,底層數組每次增加的長度 61 */ 62 public SequenceStack(T element, int initSize, int capacityIncrement) { 63 64 this.capacity = initSize; 65 this.capacityIncrement = capacityIncrement; 66 elementData = new Object[capacity]; 67 elementData[0] = element; 68 size++; 69 70 } 71 72 /** 73 * 獲取順序棧的大小 74 * 75 * @return 順序棧的大小值 76 */ 77 public int length(){ 78 79 return size; 80 81 } 82 83 /** 84 * 入棧 85 * 86 * @param element 入棧的元素 87 */ 88 public void push(T element) { 89 90 ensureCapacity(size + 1); 91 elementData[size++] = element; 92 93 } 94 95 /** 96 * 確認數組的長度是否滿足push之后的長度 97 * 98 * @param minCapacity 數組需要的最小長度 99 */ 100 public void ensureCapacity(int minCapacity) { 101 102 // 如果數組的原有長度小於目前所需要的長度 103 if (minCapacity > capacity) { 104 105 if (capacityIncrement > 0) { 106 107 while (capacity < minCapacity) { 108 // 不斷地將capacity長度加capacityIncrement 109 // 直到capacity大於minCapacity為止 110 capacity += capacityIncrement; 111 112 } 113 } else { 114 115 // 不斷地將capacity * 2,直到capacity大於minCapacity為止 116 while (capacity < minCapacity) { 117 118 capacity <<= 1; 119 120 } 121 122 } 123 elementData = Arrays.copyOf(elementData, capacity); 124 } 125 126 } 127 128 /** 129 * 出棧 130 * 131 * @return 出棧的元素 132 */ 133 public T pop() { 134 135 T oldValue = (T) elementData[size - 1]; 136 // 釋放棧頂元素 137 elementData[--size] = null; 138 return oldValue; 139 140 } 141 142 // 返回棧頂元素,但不刪除棧頂元素 143 public T peek() { 144 145 return (T) elementData[size - 1]; 146 147 } 148 149 // 判斷順序棧是否為空 150 public boolean empty() { 151 152 return size == 0; 153 154 } 155 156 // 清空順序棧 157 public void clear() { 158 159 // 將底層數組所有元素賦值為null 160 Arrays.fill(elementData, null); 161 size = 0; 162 163 } 164 165 public String toString() { 166 167 if (size == 0) { 168 169 return "[]"; 170 171 } else { 172 173 StringBuilder sb = new StringBuilder("["); 174 for (int i = size - 1; i > -1; i--) { 175 sb.append(elementData[i].toString() + ", "); 176 } 177 int len = sb.length(); 178 return sb.delete(len - 2, len).append("]").toString(); 179 } 180 181 } 182 183 }
測試類:
1 package com.ietree.basic.datastructure.stack; 2 3 /** 4 * Created by ietree 5 * 2017/4/29 6 */ 7 public class SequenceStackTest { 8 9 public static void main(String[] args) { 10 11 SequenceStack<String> stack = new SequenceStack<String>(); 12 13 stack.push("aaaa"); 14 stack.push("bbbb"); 15 stack.push("cccc"); 16 stack.push("dddd"); 17 System.out.println(stack); 18 19 System.out.println("訪問棧頂元素:" + stack.peek()); 20 21 System.out.println("第一次彈出棧頂元素:" + stack.pop()); 22 23 System.out.println("第二次彈出棧頂元素:" + stack.pop()); 24 25 System.out.println("兩次pop之后的棧:" + stack); 26 27 } 28 29 }
程序輸出:
[dddd, cccc, bbbb, aaaa]
訪問棧頂元素:dddd
第一次彈出棧頂元素:dddd
第二次彈出棧頂元素:cccc
兩次pop之后的棧:[bbbb, aaaa]