Java 模拟“栈数据结构”
这是之前学习中碰到的一个较好的实例,感觉很有意义,拿出来记录一下!程序的内容包括类、异常等。
代码如下:
- 首先定义一个 MyStack 类:
/**
* 模拟栈:使用一位数组模拟栈的数据结构,假设栈的默认容量为 5
* 实现功能:
* 1、可以存储 Java 中任意类型的数据
* 2、提供 push 方法模拟压栈(栈满了,要有提示信息)
* 3、提供 pop 方法模拟弹栈(栈空了,要有提示信息)
* 4、设置栈帧,指向栈顶元素
* 5、编写测试程序
*
*/
public class MyStack {
// 栈可以存放任意类型的数据,存到栈中即表示存到数组中
private Object[] elements;
// 栈帧,指向顶部元素
private int index;
/*
设置 set 和 get 方法
*/
public Object[] getElements() {
return elements;
}
public void setElements(Object[] elements) {
this.elements = elements;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
/*
无参数的构造方法
*/
public MyStack() {
// 默认容量为 5
this.elements = new Object[5];
this.index = -1;
}
/*
有参数的构造方法
*/
public MyStack(Object[] elements) {
this.elements = elements;
}
/*
压栈方法
*/
public void push(Object obj){
if (this.index >= elements.length-1){
System.out.println("栈已满,压栈失败!");
return;
}
// this.index++;
this.elements[++index] = obj;
System.out.println("压入" + obj + "元素成功,栈帧指向:" + index);
}
/*
弹栈方法
*/
public void pop(){
if (this.index <= -1){
System.out.println("栈已空,弹栈失败!");
return;
}
System.out.print("弹出" + elements[index] + "成功,");
this.elements[index--] = null;
System.out.println("栈帧指向:" + index);
}
}
- 然后是一个测试程序:
public class Test {
public static void main(String[] args) {
MyStack ms = new MyStack();
ms.push(new Object());
ms.push(new Object());
ms.push(new Object());
ms.push(new Object());
ms.push(new Object());
ms.push(new Object()); // 这里栈满了
System.out.println("-------------------------------------------------------");
ms.pop();
ms.pop();
ms.pop();
ms.pop();
ms.pop();
ms.pop(); // 这里栈空了
}
}
结果如下:
压入java.lang.Object@70177ecd元素成功,栈帧指向:0
压入java.lang.Object@1e80bfe8元素成功,栈帧指向:1
压入java.lang.Object@66a29884元素成功,栈帧指向:2
压入java.lang.Object@4769b07b元素成功,栈帧指向:3
压入java.lang.Object@cc34f4d元素成功,栈帧指向:4
栈已满,压栈失败!
-------------------------------------------------------
弹出java.lang.Object@cc34f4d成功,栈帧指向:3
弹出java.lang.Object@4769b07b成功,栈帧指向:2
弹出java.lang.Object@66a29884成功,栈帧指向:1
弹出java.lang.Object@1e80bfe8成功,栈帧指向:0
弹出java.lang.Object@70177ecd成功,栈帧指向:-1
栈已空,弹栈失败!
可以看出:最后进栈的元素最先被弹出来,达到了实现的目标
但是这里的 “栈满” 或者 “栈空” 的表达可以考虑写的更完美一些,比如使用异常机制来做。因此下面再加入一个自定义的异常类,取名:MyStackOperationException
- MyStackOperationException 代码:
public class MyStackOperationException extends Exception{
/*
无参数的异常构造方法
*/
public MyStackOperationException(){
}
/*
有参数的异常构造方法
*/
public MyStackOperationException(String s){
super(s);
}
}
- 此时的 MyStack 代码代码修改为:
/**
* 模拟栈:使用一位数组模拟栈的数据结构,假设栈的默认容量为 5
* 实现功能:
* 1、可以存储 Java 中任意类型的数据
* 2、提供 push 方法模拟压栈(栈满了,要有提示信息)
* 3、提供 pop 方法模拟弹栈(栈空了,要有提示信息)
* 4、设置栈帧,指向栈顶元素
* 5、编写测试程序
*
*/
public class MyStack {
// 栈可以存放任意类型的数据,存到栈中即表示存到数组中
private Object[] elements;
// 栈帧,指向顶部元素
private int index;
/*
设置 set 和 get 方法
*/
public Object[] getElements() {
return elements;
}
public void setElements(Object[] elements) {
this.elements = elements;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
/*
无参数的构造方法
*/
public MyStack() {
// 默认容量为 5
this.elements = new Object[5];
this.index = -1;
}
/*
有参数的构造方法
*/
public MyStack(Object[] elements) {
this.elements = elements;
}
/*
压栈方法
*/
public void push(Object obj) throws MyStackOperationException {
if (this.index >= elements.length-1){
// System.out.println("栈已满,压栈失败!");
// return;
throw new MyStackOperationException("栈已满,压栈失败!");
}
// this.index++;
this.elements[++index] = obj;
System.out.println("压入" + obj + "元素成功,栈帧指向:" + index);
}
/*
弹栈方法
*/
public void pop() throws MyStackOperationException {
if (this.index <= -1){
// System.out.println("栈已空,弹栈失败!");
// return;
throw new MyStackOperationException("栈已空,弹栈失败!");
}
System.out.print("弹出" + elements[index] + "成功,");
this.elements[index--] = null;
System.out.println("栈帧指向:" + index);
}
}
- 再次测试:
public class Test {
public static void main(String[] args) {
MyStack ms = new MyStack();
try {
ms.push(new Object());
ms.push(new Object());
ms.push(new Object());
ms.push(new Object());
ms.push(new Object());
ms.push(new Object()); // 这里栈满了
} catch (MyStackOperationException e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
System.out.println("-------------------------------------------------------");
try {
ms.pop();
ms.pop();
ms.pop();
ms.pop();
ms.pop();
ms.pop(); // 这里栈空了
} catch (MyStackOperationException e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
结果如下:
压入java.lang.Object@70177ecd元素成功,栈帧指向:0
压入java.lang.Object@1e80bfe8元素成功,栈帧指向:1
压入java.lang.Object@66a29884元素成功,栈帧指向:2
压入java.lang.Object@4769b07b元素成功,栈帧指向:3
压入java.lang.Object@cc34f4d元素成功,栈帧指向:4
栈已满,压栈失败!
-------------------------------------------------------
弹出java.lang.Object@cc34f4d成功,栈帧指向:3
弹出java.lang.Object@4769b07b成功,栈帧指向:2
弹出java.lang.Object@66a29884成功,栈帧指向:1
弹出java.lang.Object@1e80bfe8成功,栈帧指向:0
弹出java.lang.Object@70177ecd成功,栈帧指向:-1
栈已空,弹栈失败!