⭐ 作者:小胡_不糊涂
作者主页:小胡_不糊涂的个人主页
收录专栏:浅谈数据结构
持续更文,关注博主少走弯路,谢谢大家支持
栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。
栈中的数据元素遵守**LIFO(Last In First Out)**的原则
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据在栈顶。
方法 | 功能 |
---|---|
Stack() | 构造一个空的栈 |
E push(E e) | 将e入栈,并返回e |
E pop() | 将栈顶元素出栈并返回 |
E peek() | 获取栈顶元素 |
int size() | 获取栈中有效元素个数 |
boolean empty() | 检测栈是否为空 |
上述方法的实现:
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Stack<Integer> s = new Stack();
s.push(1);
s.push(2);
s.push(3);
s.push(4);
System.out.println(s.size()); // 获取栈中有效元素个数---> 4
System.out.println(s.peek()); // 获取栈顶元素---> 4
s.pop(); // 4出栈,栈中剩余1 2 3,栈顶元素为3
System.out.println(s.pop()); // 3出栈,栈中剩余1 2 栈顶元素为3
if (s.empty()) {
System.out.println("栈空");
} else {
System.out.println(s.size());
}
}
}
从下图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的。
模拟实现栈:
public class MyStack{
private int[] elem;
private int usedSize;//可以存放数据元素的下标
private static final int DEFAULT_CAPACITY = 10;//默认容量
public MyStack() {
elem = new int[DEFAULT_CAPACITY];
}
//入栈
public void push(int x) {
if(full()) {
elem = Arrays.copyOf(elem,2*elem.length);//扩容
}
elem[usedSize] = x;
usedSize++;
}
//判断栈满
public boolean full() {
if(usedSize == elem.length) {
return true;
}
return false;
}
//出栈
public int pop() {
if(empty()) {
throw new EmptyException("栈空了!");
}
int old = elem[usedSize-1];
usedSize--;//相当于是删除
return old;
}
//返回栈顶元素
public int peek() {
if(empty()) {
throw new EmptyException("栈空了!");
}
return elem[usedSize-1];
}
//计算入栈元素长度
public int size() {
return usedSize;
}
//判断栈空
public boolean empty() {
return usedSize == 0;
}
}
- 若进栈序列为1,2,3,4,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A: 1,4,3,2 B: 2,3,4,1 C: 3,1,4,2 D: 3,4,2,1
2.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的顺序是()。
A: 12345ABCDE B: EDCBA54321 C: ABCDE12345 D: 54321EDCBA
第一题答案为C。在序列进栈时,也可以有元素出栈,于是出栈的序列就有:1,2,3,4;1,4,3,2;2,3,4,1;3,4,2,1等等。C选项中,3先出栈,栈顶元素变为2,1不可能先出。
第二题答案为B,序列全部进栈,然后按照后进先出原则出栈。
//递归方式
void printList (Node head){
if(null != head) {
printList(head.next);
System.out.print(head.val + " ");
}
}
// 循环方式
void printList (Node head){
if (null == head) {
return;
}
Stack<Node> s = new Stack<>();
// 将链表中的结点保存在栈中
Node cur = head;
while (null != cur) {
s.push(cur);
cur = cur.next;
}
// 将栈中的元素出栈
while (!s.empty()) {
System.out.print(s.pop().val + " ");
}
}
public boolean isValid(String s) {
Stack<Character> stack=new Stack<>();
for(int i=0;i<s.length();i++){
char ch1=s.charAt(i);
if(ch1=='(' || ch1=='[' || ch1=='{'){
stack.push(ch1);
}else{
if(stack.empty()){
return false;//没有与右括号对应的元素
}
char ch2=stack.peek();
if(ch2=='('&&ch1==')' ||ch2=='['&&ch1==']' || ch2=='{'&&ch1=='}'){
stack.pop();
}else{
return false;
}
}
}
//遍历完数组后,若栈不为空,即匹配失败
if(!stack.empty()){
return false;
}
return true;
}