赞
踩
栈是一种数据结构,它是一种受限制的线性表,只能在一端添加或删除元素,具有特定的操作规则。栈的特点是先进后出(LIFO,Last In First Out),即最后入栈的元素最先出栈,而最先入栈的元素最后出栈
栈只能在一端删除或者添加元素,这一端称为栈顶
另外一端称为栈底
在超市购物时,将购买的商品放入购物篮或购物车中,形成一层一层的堆叠,就像是在组织一个临时的栈结构。
在餐厅用餐时,将盘子一层一层地叠放在餐桌上,然后按照用餐的顺序依次清理,就像是在处理一个栈结构。
在电脑中,浏览器的后退按钮就是一个栈结构,每次点击后退按钮就会返回上一个浏览页面,就像是在操作一个栈结构。
java已经给我们提供了实现类 Stack
empty(): 这个方法通常用于检查栈是否为空。
peek(): 返回栈顶的元素但不移除它。
pop(): 移除并返回栈顶的元素。
push(element): 将指定的元素压入栈顶。
search(element): 在栈中搜索指定的元素并返回其位置,其中最顶部的元素位置为1。
代码示例
- package stack;
-
- import java.util.Stack;
-
- public class test {
- public static void main(String[] args) {
- Stack<Integer> stack = new Stack<Integer>();
-
- // 将元素压入栈
- stack.push(5);
- stack.push(10);
- stack.push(15);
-
- // 查看栈顶元素
- System.out.println("栈顶元素: " + stack.peek());
-
- // 弹出栈顶元素
- int poppedElement = stack.pop();
- System.out.println("弹出的元素: " + poppedElement);
-
- // 检查栈是否为空
- System.out.println("栈是否为空? " + stack.isEmpty());
-
- // 搜索元素
- int index = stack.search(10);
- System.out.println("元素10在栈中的位置: " + index);
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
运行结果:
顺序栈使用数组实现,可以用动态数组arraylist,也可以用静态数组,我这里采用后者
我这里初始化栈顶指针为-1,代表当前栈顶指针永远指向当前元素,有的小伙伴可能会初始化栈 顶指针为0,代表栈顶指针永远指向当前元素的下一个元素
- private int top;//栈顶指针
- private int maxSize;//最大长度
- private int[] arr;
-
- public ArrayStack() {
- this.top = -1; // 栈顶指针
- maxSize = 5; // 初始最大长度
- arr = new int[maxSize];
- }
如果当前栈顶指针等于初始值-1,那这个栈就是空的,这个没有什么好说的,如果刚开始初始化栈顶指针等于0,那么这里就应该判断栈顶指针是否等于0
- public boolean isEmpty() {
- return top == -1;
- }
只要当前栈顶指针等于最大长度等于maxsize-1,那么这个栈就满了, 如果刚开始初始化栈顶指针等于0,那么这里就应该判断栈顶指针是否等于maxsize,而不是maxsize-1;
- public boolean isFull() {
- return top == maxSize - 1;
- }
入栈之前一定要判断栈是否满了,满了就扩容,如果用的是动态数组,就不需要自己扩容,程序会帮你扩容 然后后移指针
- public void push(int data) {
- // 判断栈满
- if (isFull()) {
- // 扩容,扩大到原来的两倍
- int[] newArray = Arrays.copyOf(arr, 2 * arr.length);
- arr = newArray;
- maxSize = 2 * maxSize;
- }
- arr[++top] = data;
- }
出栈的话,一定要先保存当前指针值,然后再前移指针
- public int pop() {
- if (isEmpty()) {
- throw new EmptyStackException();
- } else {
- int val = arr[top];
- top--;
- return val;
- }
- }
取栈顶元素和出栈差不多,只不过出栈需要移动栈顶指针
- public int peek() {
- if (isEmpty()) {
- throw new EmptyStackException();
- } else {
- int val = arr[top];
- return val;
- }
- }
- class ArrayStack {
- private int top;//栈顶指针
- private int maxSize;//最大长度
- private int[] arr;
-
- public ArrayStack() {
- this.top = -1; // 栈顶指针
- maxSize = 5; // 初始最大长度
- arr = new int[maxSize];
- }
-
- // 入栈
- public void push(int data) {
- // 判断栈满
- if (isFull()) {
- // 扩容,扩大到原来的两倍
- int[] newArray = Arrays.copyOf(arr, 2 * arr.length);
- arr = newArray;
- maxSize = 2 * maxSize;
- }
- arr[++top] = data;
- }
-
- // 出栈
- public int pop() {
- if (isEmpty()) {
- throw new EmptyStackException();
- } else {
- int val = arr[top];
- top--;
- return val;
- }
- }
- //取栈顶元素
- public int peek() {
- if (isEmpty()) {
- throw new EmptyStackException();
- } else {
- int val = arr[top];
- return val;
- }
- }
-
- // 判断满
- public boolean isFull() {
- return top == maxSize - 1;
- }
-
- // 判断非空
- public boolean isEmpty() {
- return top == -1;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
链表栈和数组实现的栈的基本功能是相似的,都是遵循后进先出(LIFO)的原则。不过,链表栈不需要像数组实现的栈一样进行判断是否已满,也不需要扩容。这是因为链表在内存中可以动态地分配空间,因此可以根据需要动态地增加或减少节点,从而避免了数组实现的栈可能遇到的容量限制和扩容问题。
这里直接上完整代码
我这里用到是泛型类
- class LinkedListStack<T> {
- private Node<T> head;
-
- // 入栈
- public void push(T data) {
- // 头插法
- head = new Node<>(data, head);
- }
-
- // 出栈
- public T pop() {
- if (isEmpty()) {
- throw new IllegalStateException("Stack is empty");
- }
- T data = head.data;
- head = head.next;
- return data;
- }
-
- // 打印栈顶元素
- public T peek() {
- if (isEmpty()) {
- throw new IllegalStateException("Stack is empty");
- }
- return head.data;
- }
-
- // 判断栈为空
- public boolean isEmpty() {
- return head == null;
- }
-
- // 节点类
- private static class Node<T> {
- T data;
- Node<T> next;
-
- public Node(T data, Node<T> next) {
- this.data = data;
- this.next = next;
- }
- }
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。