目录
一、栈(Stack)是什么?
栈
:一种特殊的线性表,其
只允许在固定的一端进行插入和删除元素操作
。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO
(
Last In First Out
)的原则。
压栈:栈的插入操作叫做进栈
/
压栈
/
入栈,
入数据在栈顶
。
出栈:栈的删除操作叫做出栈。
出数据在栈顶
。
![](https://img-blog.csdnimg.cn/ef0155bd01d748feb555b90225df77f1.png)
![](https://img-blog.csdnimg.cn/d488c89884c14ae797c3f368a2432ba7.png)
二、栈的使用
1.栈的方法
Stack() 构造一个空的栈
E push(E e) 将 e 入栈,并返回eE pop() 将栈顶元素出栈并返回E peek() 获取栈顶元素int size() 获取栈中有效元素个数boolean empty() 检测栈是否为空
1.1栈的模拟实现
我们首先新建一个栈。
我们还是将所需要的方法放在一个接口里方便我们调用
1.1.1判断栈是否为空
boolean empty();
我们先构造一个栈,定义它的大小。
如果栈为空我们就返回usedsize为0;
@Override
public boolean empty(){
return usedSize ==0;
}
1.1.2进栈 void push(int x);
@Override
public void push(int x) {
if(full()){
elem = Arrays.copyOf(elem,2*elem.length);//二倍扩容
}
elem[usedSize] = x;//最后一位
usedSize ++;
}
我们用一个full方法判断栈是否满了,如果满了,抛出一个异常同时扩容。
@Override
public boolean full() {
if(usedSize ==elem.length){
return true;
}
return false;
}
//抛异常
public class EmptyException extends RuntimeException{
public EmptyException(String msg){
super(msg);
}
}
1.1.3出栈,删除元素 int pop();
@Override
public int pop() {
if(empty()){
//return -1;
throw new EmptyException("栈空了");
}
int old = elem[usedSize-1];
usedSize--;//相当于删除
//elem[used] =null如果是引用类型
return old;
}
1.1.4返回栈顶元素的值 int peek();
@Override
public int peek() {
if(empty()){
//return -1;
throw new EmptyException("栈空了");
}
return elem[usedSize-1];
}
1.1.5 栈的长度 int size();
@Override
public int size() {
return usedSize;
}
2.栈的应用场景
2.1. 改变元素的序列
1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()A: 1,4,3,2 B: 2,3,4,1 C: 3,1,4,2 D: 3,4,2,1
根据给定的进栈序列为1, 2, 3, 4,进栈过程中可以出栈的规则是栈顶元素必须是当前要出栈的元素。
对于选项 A: 1, 4, 3, 2,出栈序列的第一个元素是 1,符合栈顶元素要求,不排除的可能性。
对于选项 B:
- 栈:[1,2]
- 待入栈元素:[3,4]
- 当前出栈元素:2
- 栈顶元素不等于当前出栈元素,将待入栈元素列表中的下一个元素加入栈中。
- 栈:[1,2,3]
- 栈顶元素不等于当前出栈元素,将待入栈元素列表中的下一个元素加入栈中。
- 栈:[1,2,3,4]
- 栈顶元素等于当前出栈元素,将栈顶元素出栈。
- B可能是
对于选项 C: 3, 1, 4, 2,出栈序列的第一个元素是 3,而进栈序列中 3 的后面有元素,排除的可能性。
对于选项 D: 3, 4, 2, 1,出栈序列的第一个元素是 3,而进栈序列中 3 的后面没有元素,所以可以立即出栈。接下来的出栈序列应该是 4, 2, 1,符合栈顶元素要求,不排除的可能性。
栈的问题最好画图解决,更加好理解。
2.2将递归转化为循环
比如:逆序打印链表
//递归方式
voidprintList(Nodehead){
if(null!=head){
printList(head.next);
System.out.print(head.val+"");
}
}
//循环方式
voidprintList(Nodehead){
if(null==head){
return;
}
Stack<Node>s=newStack<>(); //将链表中的结点保存在栈中
Nodecur=head;
while(null!=cur){
s.push(cur);
cur=cur.next;
}
总结
以上就是今天要讲的内容.希望大家多多支持.