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]

 

posted @ 2017-04-30 10:01  远近啊  阅读(3028)  评论(0编辑  收藏  举报