上文栈的简单实现(一)实现了不能扩展栈容量的顺序栈结构,这次给栈加上扩容功能,这样就不用担心出现满栈的情况了。
不过由于本人技术水平不够,也还在学习当中,因此只能固定扩大大小,而不是根据实际情况进行最合适的扩大。
跟上文代码差不多,只是新增了一个扩容的方法,以及改变了push方法。
新增代码如下:
/**
* 扩大栈的容量
*/
private void expanedList() {
nLen += DEFAULT_EXPANSION_LENGTH;
Object[] objNewData = new Object[nLen];
System.arraycopy(objData, 0, objNewData, 0, nTop + 1);
objData = objNewData;
}
修改代码如下:
/**
* 入栈操作
*
* @param stack
* 栈的对象引用
* @param eData
* 要压入栈的数据
*/
void push(Stack2<E> stack, E eData) {
if (isFull(stack)) {
expanedList();
}
stack.objData[++stack.nTop] = eData;
System.out.println(stack.objData[stack.nTop] + "已入栈");
}
完整代码如下:
package ds.stack;
/**
* 简单可变长栈
*
* @author Abyss_CMG
*
* @param <E>
*/
public class Stack2<E> {
private static final int DEFAULT_LENGTH = 50;// 栈的默认最大长度
private static final int DEFAULT_EXPANSION_LENGTH = 10;// 扩大容量时的默认长度
private Object[] objData = null; // 存放栈的数据的数组
private int nTop;// 用于标记栈顶
private int nLen;// 用于标记栈的最大长度
/**
* 若实例化栈时没有参数,则使用默认长度50初始化栈
*/
Stack2() {
this(DEFAULT_LENGTH);
}
/**
* 实例化栈结构
*
* @param nInitSize
* 栈的最大长度
*/
Stack2(int nInitSize) {
if (nInitSize > 0) {
objData = new Object[nInitSize];
nTop = -1;
nLen = nInitSize;
} else {
System.out.println("栈的初始化长度不能小于等于0:" + nInitSize);
}
}
/**
* 获取栈中已存放数据的长度
*
* @param stack
* 栈的对象引用
* @return 获取栈中已存放数据的长度
*/
int getSize(Stack2<E> stack) {
return stack.nTop + 1;
}
/**
* 获取栈的最大长度
*
* @param stack
* 栈的对象引用
* @return 栈的最大长度(初始化时的长度)
*/
int getMaxSize(Stack2<E> stack) {
return stack.nLen;
}
/**
* 判断是否满栈
*
* @param stack
* 实例化的对象引用
* @return 若满栈则返回true,否则返回false
*/
boolean isFull(Stack2<E> stack) {
return (getSize(stack) == stack.nLen) ? true : false;
}
/**
* 判断是否空栈
*
* @param stack
* 栈的对象引用
* @return 若空栈则返回true,否则返回false
*/
boolean isEmpty(Stack2<E> stack) {
return (stack.nTop == -1) ? true : false;
}
/**
* 清空栈,但不释放内存
*
* @param stack
* 栈的对象引用
*/
void clear(Stack2<E> stack) {
if (stack.nTop != -1) {
stack.nTop = -1;
}
}
/**
* 释放栈的内存空间
*
* @param stack
* 栈的对象引用
*/
void free(Stack2<E> stack) {
stack.clear(stack);
if (stack != null) {
stack = null;
}
}
/**
* 扩大栈的容量
*/
private void expanedList() {
nLen += DEFAULT_EXPANSION_LENGTH;
Object[] objNewData = new Object[nLen];
System.arraycopy(objData, 0, objNewData, 0, nTop + 1);
objData = objNewData;
}
/**
* 入栈操作
*
* @param stack
* 栈的对象引用
* @param eData
* 要压入栈的数据
*/
void push(Stack2<E> stack, E eData) {
if (isFull(stack)) {
expanedList();
}
stack.objData[++stack.nTop] = eData;
System.out.println(stack.objData[stack.nTop] + "已入栈");
}
/**
* 将栈顶弹出
*
* @param stack
* 栈的对象引用
* @return 弹出栈顶数据
*/
@SuppressWarnings("unchecked")
E pop(Stack2<E> stack) {
if (isEmpty(stack)) {
System.out.println("栈已空,无法出栈");
return null;
}
System.out.println(stack.objData[stack.nTop] + "已出栈");
return (E) stack.objData[stack.nTop--];
}
/**
* 读取栈顶数据(不弹出)
*
* @param stack
* 栈的对象引用
* @return 返回栈顶元素
*/
@SuppressWarnings("unchecked")
E peek(Stack2<E> stack) {
if (isEmpty(stack)) {
System.out.println("栈已空,无法读取栈顶元素");
return null;
}
System.out.println(stack.objData[stack.nTop] + "已读取");
return (E) stack.objData[stack.nTop];
}
}
测试代码:
package ds.stack;
public class Simple2 {
public static void main(String[] args) {
System.out.println("----新建空栈----");
Stack2<String> stack = new Stack2<String>(5);
System.out.println("栈的最大长度:" + stack.getMaxSize(stack));
System.out.println("栈的现有长度:" + stack.getSize(stack));
System.out.println("----测试入栈操作----");
for (int i = 1; i <= 6; i++) {
System.out.println("将test" + i + "压入栈");
stack.push(stack, "test" + i);
}
System.out.println("栈的现有长度:" + stack.getSize(stack));
System.out.println("栈的最大长度:" + stack.getMaxSize(stack));
System.out.println("----测试清空栈操作----");
stack.free(stack);
System.out.println("栈的现有长度:" + stack.getSize(stack));
System.out.println("栈的最大长度:" + stack.getMaxSize(stack));
}
}
测试结果:
----新建空栈----
栈的最大长度:5
栈的现有长度:0
----测试入栈操作----
将test1压入栈
test1已入栈
将test2压入栈
test2已入栈
将test3压入栈
test3已入栈
将test4压入栈
test4已入栈
将test5压入栈
test5已入栈
将test6压入栈
test6已入栈
栈的现有长度:6
栈的最大长度:15
----测试清空栈操作----
栈的现有长度:0
栈的最大长度:15