数据结构之栈结构
栈结构:线性结构。从数据的存储结构来进一步划分,栈结构包括两类:
顺序栈结构:使用一组地址连续的内存单元依次保存栈中的数据;
链式栈结构:使用链表形式保存栈中各元素的值;
在栈结构中只能在一端进行操作,该操作端称为栈顶,另一端称为栈底。保存和取出数据都只能从栈结构的一端进行。
栈结构是按照"后进先出"的原则处理结点数据的。
1 Java实现的栈: 2 3 /** 4 * 栈: 先进后出,后进先出 的线性表(LIFO). 限定仅在表尾进行插入和删除操作的线性表. 5 * 6 * @see java.util.ArrayDeque 7 */ 8 public class xStack<E> { 9 10 Object[] elements; 11 12 int bottom; // 栈底. index=0 13 14 int top; // 栈顶.进行插入,删除等操作. 15 16 private static final int DEFAULT_INITIAL_CAPACITY = 1 << 3; 17 18 private static final int MAX_CAPACITY = 1 << 16; 19 20 /** 21 * 构造 22 */ 23 public xStack() { 24 elements = new Object[DEFAULT_INITIAL_CAPACITY]; 25 } 26 27 /** 28 * 构造 29 * 30 * @param c 31 */ 32 public xStack(Collection<? extends E> c) { 33 elements = new Object[calculateSize(c.size())]; 34 addAll(c); 35 } 36 37 /* 计算stack大小 */ 38 private int calculateSize(int capacity) { 39 if (capacity < DEFAULT_INITIAL_CAPACITY) 40 return DEFAULT_INITIAL_CAPACITY; 41 return Math.min((int) Math.pow(2, capacity >> 2), MAX_CAPACITY); 42 } 43 44 /** 45 * 压入若干个元素 46 * 47 * @param c 48 * @return 49 */ 50 public boolean addAll(Collection<? extends E> c) { 51 boolean modified = false; 52 for (E e : c) 53 if (add(e)) 54 modified = true; 55 return modified; 56 } 57 58 /** 59 * 压入一个元素 60 * 61 * @param e 62 * @return 63 */ 64 public boolean add(E e) { 65 Objects.requireNonNull(e); 66 int length = elements.length - 1; 67 if (top < length) { 68 elements[top] = e; 69 top++; 70 } else if (top == length) { 71 doubleCapacity(); // 扩容 72 elements[top] = e; 73 top++; 74 } 75 return true; 76 } 77 78 /* 扩容 */ 79 private void doubleCapacity() { 80 int blank = elements.length; 81 int newCapacity = Math.min(blank << 1, MAX_CAPACITY); 82 if (newCapacity < 0) 83 throw new IllegalStateException("xStack too big"); 84 Object[] o = new Object[newCapacity]; 85 System.arraycopy(elements, 0, o, 0, blank); 86 elements = o; 87 } 88 89 /** 90 * 测试栈是否为空 91 */ 92 public boolean isEmpty() { 93 return bottom == top; 94 } 95 96 /** 97 * 查看栈顶,但不移除. 允许返回null 98 */ 99 @SuppressWarnings("unchecked") 100 public E getTop() { 101 return (E) elements[top - 1]; 102 } 103 104 /** 105 * 从栈顶弹出一个元素(top). 106 */ 107 public E pop() { 108 int h = top; 109 @SuppressWarnings("unchecked") 110 E result = (E) elements[h - 1]; 111 if (result == null) 112 return null; 113 elements[h - 1] = null; 114 Object[] o = new Object[elements.length]; 115 System.arraycopy(elements, 0, o, 0, h); 116 elements = o; 117 top--; 118 return result; 119 } 120 121 /** 122 * 将元素压入栈顶(top). 123 */ 124 public void push(E e) { 125 Objects.requireNonNull(e); 126 int length = elements.length - 1; 127 if (top < length) { 128 elements[top] = e; 129 top++; 130 } else if (top == length) { 131 doubleCapacity(); // 扩容 132 elements[top] = e; 133 top++; 134 } 135 } 136 137 /** 138 * 返回元素在栈中的位置 139 */ 140 public int search(Object o) { 141 if (o == null) 142 return -1; 143 int mask = elements.length - 1; 144 Object obj = null; 145 int i = bottom; 146 while ((obj = elements[i]) != null) { 147 if (o.equals(obj)) 148 return i; 149 i = (i + 1) & mask; 150 } 151 return -1; 152 } 153 154 /** 155 * 返回栈的深度 156 */ 157 public int deep() { 158 return (top - bottom) & (elements.length - 1); 159 } 160 161 /** 162 * 返回stack对象的字符串表示 163 */ 164 public String toString() { 165 if (deep() == 0) 166 return "[]"; 167 Object[] o = Arrays.copyOf(elements, deep()); 168 return Arrays.toString(o); 169 } 170 171 }