一、栈的基本定义

栈是一种数据结构,它代表一种特殊的线性表,这种线性表只能在固定一端(通常认为是线性表的尾端)进行插入、删除操作的特殊线性表,通常就是在线性表的尾端进行插入、删除操作。

二、顺序栈的实现

顺序栈是利用一组地址连续的存储单元依次存放从栈底到栈顶的数据元素,栈底位置固定不变,它的栈顶元素可以直接通过顺序栈底层数组的数组元素arr[size - 1]来访问。

 package com.ietree.basic.datastructure.stack;

 import java.util.Arrays;

 /**
* 顺序栈
*
* Created by ietree
* 2017/4/29
*/
public class SequenceStack<T> { private int DEFAULT_SIZE = 10;
// 保存数组的长度
private int capacity;
// 定义当底层数组容量不够时,程序每次增加的数组长度
private int capacityIncrement = 0;
// 定义一个数组用于保存顺序栈的元素
private Object[] elementData;
// 保存顺序栈中元素的当前个数
private int size = 0; // 以默认数组长度创建空顺序栈
public SequenceStack() { capacity = DEFAULT_SIZE;
elementData = new Object[capacity]; } // 以一个初始化元素来创建顺序栈
public SequenceStack(T element) { this();
elementData[0] = element;
size++; } /**
* 以指定长度的数组来创建顺序线性表
*
* @param element 指定顺序栈中第一个元素
* @param initSize 指定顺序栈底层数组的长度
*/
public SequenceStack(T element, int initSize) { this.capacity = initSize;
elementData = new Object[capacity];
elementData[0] = element;
size++; } /**
* 以指定长度的数组来创建顺序栈
*
* @param element 指定顺序栈中第一个元素
* @param initSize 指定顺序栈底层数组的长度
* @param capacityIncrement 指定当顺序栈底层数组的长度不够时,底层数组每次增加的长度
*/
public SequenceStack(T element, int initSize, int capacityIncrement) { this.capacity = initSize;
this.capacityIncrement = capacityIncrement;
elementData = new Object[capacity];
elementData[0] = element;
size++; } /**
* 获取顺序栈的大小
*
* @return 顺序栈的大小值
*/
public int length(){ return size; } /**
* 入栈
*
* @param element 入栈的元素
*/
public void push(T element) { ensureCapacity(size + 1);
elementData[size++] = element; } /**
* 确认数组的长度是否满足push之后的长度
*
* @param minCapacity 数组需要的最小长度
*/
public void ensureCapacity(int minCapacity) { // 如果数组的原有长度小于目前所需要的长度
if (minCapacity > capacity) { if (capacityIncrement > 0) { while (capacity < minCapacity) {
// 不断地将capacity长度加capacityIncrement
// 直到capacity大于minCapacity为止
capacity += capacityIncrement; }
} else { // 不断地将capacity * 2,直到capacity大于minCapacity为止
while (capacity < minCapacity) { capacity <<= 1; } }
elementData = Arrays.copyOf(elementData, capacity);
} } /**
* 出栈
*
* @return 出栈的元素
*/
public T pop() { T oldValue = (T) elementData[size - 1];
// 释放栈顶元素
elementData[--size] = null;
return oldValue; } // 返回栈顶元素,但不删除栈顶元素
public T peek() { return (T) elementData[size - 1]; } // 判断顺序栈是否为空
public boolean empty() { return size == 0; } // 清空顺序栈
public void clear() { // 将底层数组所有元素赋值为null
Arrays.fill(elementData, null);
size = 0; } public String toString() { if (size == 0) { return "[]"; } else { StringBuilder sb = new StringBuilder("[");
for (int i = size - 1; i > -1; i--) {
sb.append(elementData[i].toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
} } }

测试类:

 package com.ietree.basic.datastructure.stack;

 /**
* Created by ietree
* 2017/4/29
*/
public class SequenceStackTest { public static void main(String[] args) { SequenceStack<String> stack = new SequenceStack<String>(); stack.push("aaaa");
stack.push("bbbb");
stack.push("cccc");
stack.push("dddd");
System.out.println(stack); System.out.println("访问栈顶元素:" + stack.peek()); System.out.println("第一次弹出栈顶元素:" + stack.pop()); System.out.println("第二次弹出栈顶元素:" + stack.pop()); System.out.println("两次pop之后的栈:" + stack); } }

程序输出:

[dddd, cccc, bbbb, aaaa]
访问栈顶元素:dddd
第一次弹出栈顶元素:dddd
第二次弹出栈顶元素:cccc
两次pop之后的栈:[bbbb, aaaa]
05-02 20:04