一、栈的基本概念:
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针
因此,栈有着这样的一个特点“
先进后出
”,
先进去的元素最后才能出来
为了便于理解,我们可以举一个例子,就像桶装薯片一样,因为只有一个出入口,所以我们吃进去的第一片薯片往往是包装时最后一个进去的薯片;而我们吃到最后的那一片薯片一般都是整桶薯片里第一个进去的薯片。为了便于理解在下边放一个简图来理解。
二、栈的方法:
push( object) //入栈
pop() //栈顶元素出栈
empty() //判定栈是否为空
peek() //获取栈顶元素,但不会弹出栈顶元素。
search(object) //判端元素num是否在栈中,如果在返回1,不在返回-1
三、基于数组构造一个栈:
class OrderStack<E>{
protected int top;
protected E stackArrays
public Orderstack(int capacity){
this.top=0;
this.stackArrays=(E[])new Object[capacity];
}
public boolean ifFull(){
//判满
return top==stackArrays.length;
}
public void push(E val){
//入栈
if(isFull()){
stackArrays=Arrays.copyOf(stackArrays,stackArrays.length*2);
}
stackArrays[top++]=val;
}
public boolean isEmpty(){
//判空
return top==0;
}
public E pop(){
//出栈并移除元素
if(isEmpty()){
throw new UnsupportedOperationException("the stack has been empty")
}
E result=stackArrays[top-1];
return result;
}
public E peek(){
//获取栈顶元素
if(isEmpty()){
throw new UnsupportedOperationException("the stack has been empty")
}
return stackArrays[top-1];
}
public void show(){
//打印栈内元素
for(int i=top-1;i>=0;i--){
System.out.println(stackArrays[i]+" ");
}
}
}
四、栈的经典练习题:
例题:有两个序列,第一个序列表示栈的压入序列,第二个序列表示栈的弹出序列,判断第二个序列是否为栈的正确弹出序列。
重点:第一个序列表示了栈的压入序列,但是并不代表所有元素都是被一次压入的,有可能是中间穿插着弹出然后分多次压入的。
举例:序列1:12345
可能的操作:压入12、弹出2、压入34、弹出4、压入5然后弹出
得到的序列2:24531
思路:入栈序列是一定的,但是何时开始出栈以及出了几个是不知道的,那么模拟所有符合序列2可能的出栈方法即可。
解法:建立一个辅助栈,按照序列1的入栈顺序逐个入栈,每个元素入栈的同时与序列2的元素逐个对比,如果入辅助栈的元素与序列2的元素相等的时候,那么弹出辅助栈中的元素。当序列1中的元素全部入栈之后,则开始从辅助栈的栈顶逐个比对元素。
public static boolean isPopArrays(int[] push,int[] pop){
if(pop.length==0||pop.length==0){
System.our.println("false!");
}
Stack<Integer> stack=new<>stack;//建立辅助栈
int j=0;//表示pop中的索引
for(int i-0;i<push.length;i++){
stack.push(push[i]);
while(!stack.isempty()&&stack.peek==pop[j]){
//栈不空并且栈顶等于出栈序列的对应元素,栈弹出栈顶元素
stack.pop;
j++;
}
}
if(stack.isempty()){
//如果两个序列互相对应的话,最后栈内元素应该为空
return ture;
}
return false;
}