Java栈之顺序栈存储结构实现
一、栈的基本定义
栈是一种数据结构,它代表一种特殊的线性表,这种线性表只能在固定一端(通常认为是线性表的尾端)进行插入、删除操作的特殊线性表,通常就是在线性表的尾端进行插入、删除操作。
二、顺序栈的实现
顺序栈是利用一组地址连续的存储单元依次存放从栈底到栈顶的数据元素,栈底位置固定不变,它的栈顶元素可以直接通过顺序栈底层数组的数组元素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]
如果文章对你有所帮助的话,请点个推荐或者关注吧。也希望你能够养成分享的习惯,从而去帮助其他人。