栈是限制仅在表的一端进行插入和删除运算的线性表
(1)通常称插入、删除这一端为栈顶,另一端称栈底;
(2)当表中没有元素时称空栈;
(3)栈为先进后出(First In Last out)的线性表,简称FILO表(也作后进先出,LIFO)
栈的修改是按先进后出的原则进行,每次删除(退栈)的总是当前栈中最新的元素,即最后插入(进栈)的元素,而最新插入的是被放在栈的底部,要最后才能删除。
举个例子:元素以a1,a2,a3,a4,...,an的顺序进栈,出栈的顺序却是an,an-1,......,a1。记得教我的老师的曾说进栈出栈的顺序就像洗碗,一层层垒上去,却要从最上面拿起。
下面使用集合模拟栈的数据结构:
import java.util.ArrayList;
/**
*
* @author 小青
* @Time 下午2:50:55
* @Function:通过集合自定义一个栈
*
*/
public class MyStack{
private ArrayList<Object> list=new ArrayList<Object>(); //使用集合存储数据
//栈是否为null
public boolean isEmpty(){
return list.isEmpty();
}
//栈长度
public int size(){
return list.size();
}
//取栈顶元素
public Object stackTop(){
if(list.size()==0){
return null;
}
return list.get(list.size()-1);
}
//出栈
public Object pop(){
if(list.size() == 0){
return "对不起,栈为null,没有元素可以删除";
}
Object obj = list.get(list.size()-1);
list.remove(list.size()-1);
return obj;
}
//压栈
public void push(Object obj){
list.add(obj);
}
//toString
public String toString(){
return "MyStack:" + list.toString();
}
}
写段测试代码:
/**
*
* @author 小青
* @Time 下午2:50:55
* @Function:测试模拟栈结构
*
*/
public class TestStack {
public static void main(String[] args) {
MyStack stack = new MyStack();
System.out.println("栈是否为null:" + stack.isEmpty());
System.out.println("栈的长度:" + stack.size());
System.out.println("栈顶元素:" + stack.stackTop());
System.out.println("出栈:" + stack.pop());
System.out.println("---------------------------------");
stack.push("hello");
stack.push("world");
stack.push("Java");
System.out.println("栈是否为null:" + stack.isEmpty());
System.out.println("栈的长度:" + stack.size());
System.out.println("栈顶元素" + stack.stackTop());
System.out.println("出栈" + stack.pop());
}
}
运行截图:
可以看到,使用集合模拟栈结构,不需要考虑栈容量的问题,相对简单,下面我们使用数组模拟栈
/**
*
* @author 小青
* @Time 下午2:50:55
* @Function:通过数组自定义一个栈
*
*/
public class MyStack{
//栈的默认长度
private static int DEFAULT_LENGTH = 20;
//使用数组存储数据
private Object[] objects;
//栈容量
private int content = 0;
//栈中元素的数量
private int size = 0;
//栈指针,标记当前指向元素
private int index = 0;
public MyStack(){
this.content = MyStack.DEFAULT_LENGTH;
objects = new Object[this.content];
}
public MyStack(int content){
this.content = content;
objects = new Object[this.content];
}
// 判断栈是否为空
public boolean isEmpty() {
return size == 0;
}
// 计算当前的元素个数
public int size() {
return this.size;
}
//计算当前栈容量
public int content(){
return this.content;
}
//栈顶元素
public Object stackTop() {
if(this.size == 0) {
return null;
}
return objects[this.index-1];
}
//压栈
public void push(Object t) {
//加入数据没有超出数组容量的时候
if (this.size < this.content) {
this.objects[this.index] = t;
this.index++;
this.size++;
} else {
enlarge();//扩充栈容量
this.objects[this.index] = t;
this.index++;
this.size++;
}
}
//出栈
public Object pop() {
if(this.size == 0 ) {
return "当前栈没有数据";
}
index--;
Object obj = this.objects[this.index];
this.objects[this.index] = null;
this.size--;
return obj;
}
//扩充容量,然后把原始数据复制到新数组中,然后再赋值回数组
public void enlarge(){
System.out.println("栈容量达到当前峰值:" + this.content + ",需要扩充容量");
//设置新数组扩充的大小
this.content = this.content + MyStack.DEFAULT_LENGTH;
Object[] temp = new Object[this.content];
// 把原始数据复制到新的数组中
System.arraycopy(objects, 0, temp, 0, objects.length);
// 清空原始数据的值
Arrays.fill(objects, null);
// 把新的数组再赋值回原始数组
this.objects = temp;
}
// 清空栈数据,让数组成为初始状态
public void clear() {
System.out.println("清空栈内数据,初始化栈");
Arrays.fill(objects, null);
this.index = 0;
this.size = 0;
this.content = MyStack.DEFAULT_LENGTH;
// 重新创建一个数组
objects = new Object[this.content];
}
}
测试代码;
public class TestStack {public static void main(String[] args) {MyStack stack = new MyStack();System.out.println("栈是否为null:" + stack.isEmpty());System.out.println("栈的长度:" + stack.size());System.out.println("栈的容量:" + stack.content());System.out.println("栈顶元素:" + stack.stackTop());System.out.println("出栈:" + stack.pop());System.out.println("---------------------------------");stack.push("hello");stack.push("world");stack.push("Java");System.out.println("栈是否为null:" + stack.isEmpty());System.out.println("栈的长度:" + stack.size());System.out.println("栈的容量:" + stack.content());System.out.println("栈顶元素" + stack.stackTop());System.out.println("出栈" + stack.pop());System.out.println("栈的长度:" + stack.size());stack.clear();System.out.println("栈的长度:" + stack.size());System.out.println("栈的容量:" + stack.content());}} 运行截图:/** * * @author 小青 * @Time 下午2:50:55 * @Function:测试模拟栈结构 * */
使用数组在模拟栈结构的时候,需要考虑到数组本身长度不可变的特性,注意当长度超出容量的时候,需要进行扩容,另外,栈的长度和容量,在数组进行模拟的时候是有区别的,这点应该注意