一.栈的定义:
栈是一种数据结构,它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
栈是只能在某一端插入和删除的特殊线性表。用桶堆积物品,先堆进来的压在底下,随后一件一件往堆。取走时,只能从上面一件一件取。堆和取都在顶部进行,底部一般是不动的。
栈就是一种类似桶堆积物品的数据结构,进行删除和插入的一端称栈顶,另一堆称栈底。插入一般称为进栈(PUSH),删除则称为退栈(POP)。 栈也称为后进先出表(LIFO表)。
二.栈的实现:
为了对之前的类和对象进行练习,这次选择定义一个名为MyStack的类来表示栈。栈要有表示目前元素位置的栈顶和存放栈内数据的部分。同时作为一个类,我们也要对这个类定义一个构造函数,因为默认的构造函数只会赋值为默认的零值。
class MyStack{
private int top=-1; //栈顶
private int[] elememts;//存放栈中的元素的数组
private static int defaultCapacity = 5;
public MyStack(){
this(defaultCapacity);//this()表示调用了同一个类的另外一个构造函数
}//构造函数
public MyStack(int capacity){
this.elememts = new int[capacity];
}//构造函数
public MyStack(int[] array){
this.elememts = array;
}//构造函数
}
上边我们构造了一个类,我们为这个类定义了三个构造函数,我们在类中定义了一个静态变量defaultCapacity,用于表示一个默认的数组长度。同时因为现在栈中没有任何元素,故我们把栈顶的值top设为-1。
this(defaultCapacity)表示调用了类的另外的构造函数,而参数defaultCapacity是int类型,那么可以知道调用的函数是public MyStack(int capacity)这个构造函数。
同时,数组还是有很多操作的,例如入栈出栈这些操作。
1.入栈的实现:
首先入栈,要先判断数组长度是否够用,如果不够用要扩展数组长度,在数据入栈之后还要对栈顶值进行+1来表示新的栈顶位置。
public void push(int value){
//判满
if(this.isFull()){
//if 满 -》 扩容
elememts = Arrays.copyOf(elememts, 2*elememts.length);
}
//直接入栈
elememts[top++] = value;
//将top++与elememts[top] = value结合,更加简便;
}
public boolean isFull(){
return top == elememts.length;//判满的函数。
}
在栈的扩容方面我们选择了用数组的复制这个方法。即:
elememts = Arrays.copyOf(elememts, 2*elememts.length);
因为Arrays.copyOf的格式是Arrays.copyOf(要复制的数组, 复制后的长度);是一个可以增加长度的数组复制方式。
2.出栈的实现:
出栈,要先判断数组里边是否还有可以出的元素,如果没有的话要及时报错,在数据出栈之后还要对栈顶值进行-1来表示新的栈顶位置。
public int pop(){
if(isEmpty()){
return Integer.MAX_VALUE;//判空
}
return elememts[--top];
}
public boolean isEmpty(){
return top == -1;
}
3.获取栈顶元素但是不改变栈的结构:
public int peek(){
return elememts[top];
}
4.转换成字符串输出的方法toString:
public String toString(){
//将栈中的有效元素存放到一个String字符串中
StringBuilder strs = new StringBuilder();
for(int i=0; i<=top-1; i++){
strs.append(elememts[i]+" ");
}
return strs.toString();
}
在这里我们用了StringBuilder而不是String,因为String不可变性,导致我们每次用“+”构造新的字符串时都会新建一个StringBuilder,为了使用更加便捷,我们使用StringBuilder格式,通过append方法来进行字符串连接,最后再用toString方法转换成字符串输出。
至此,一个简单的栈就被实现了,虽然Java有自己的栈(名为Stack),但是自己实现一次也能更好地理解栈还有类和对象的相关知识。