目录
总结:环形队列是否已满条件:(tail+1)%data.length==head;
接:集合类—List、Map、Set的简单用法_林纾y的博客-CSDN博客_map put列表
引言
栈和队列都是线性表,都是基于List基础上的实现。栈和队列是一个使用上更加严格的线性表,动态数组,链表可以在任意位置进行元素的插入和删除,栈和队列不行,他们是一端插入一端删除。
线性表:数组、链表、字符串、栈、队列(元素按照一条“直线”排列,线性表这个结构中,一次添加单个元素)
一、栈(stack)
后进先出的线性表,支持三个核心操作:入栈push;出栈pop;返回栈顶元素 peek【水杯就是一个天然的栈结构,只能从杯口倒入水,从杯口倒出水】
LIFO:后进先出--Last In First Out
1.栈的应用
1)撤销操作:一般任意编译器中,撤销操作:ctrl+z
2)浏览器的前进后退:如此时页面在C页面,看完C后想返回B页面,点击后退箭头相当于将C出栈,此时栈顶就是B页面。
3)开发中程序的“调用栈”操作系统栈底层就是我们的栈实现。

分析:funA()卡在第二行入栈,funB()卡在第二行入栈,funC入栈,return开始就是出栈了
2.栈的实现
自己实现栈,栈也是一个线性表
1)基于数组实现的栈--顺序栈【数组尾部添加删除时间复杂度O(1)】,栈顶实际上就是数组末尾
2)基于链表实现的栈--链式栈【尾插和尾删】
代码:
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
/**
* 基于数组的顺序栈实现
* @param <E>
*/
public class MyStack<E> {
//当前栈的数据个数
private int size;
//实际存储数据的动态数组-ArrayList-长度不够自动扩容
private List<E> data=new ArrayList<>();
/**
* 将val入栈
* @param val
*/
public void push(E val){
//默认List集合的add是尾插
data.add(val);
size++;
}
/**
* 弹出栈顶元素,返回栈顶的值
* @return
*/
public E pop(){
if(isEmpty()){
//栈为空,没有栈顶元素,抛出异常
throw new NoSuchElementException("stack is empty!cannot pop!");
}
//删除栈顶元素
E val=data.remove(size-1);
size--;
return val;
//这三行可写成一句:return data.remove(--size);
}
/**
* 返回栈顶元素,但不出栈
* @return
*/
public E peek(){
if(isEmpty()){
throw new NoSuchElementException("stack is empty!cannot peek!");
}
return data.get(size-1);
}
/**
* 返回当前栈顶元素是否为空
* @return
*/
public boolean isEmpty(){
return size==0;
}
/**
* 打印栈的元素
* @return
*/
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append("[");
for (int i = 0; i < size; i++) {
sb.append(data.get(i));
if(i!=size-1){
sb.append(",");
}
}
sb.append("] top");
return sb.toString();
}
}
测试:
public class Test {
public static void main(String[] args) {
MyStack<Integer> myStack=new MyStack<>();
myStack.push(1);
myStack.push(3);
myStack.push(5);
System.out.println(myStack.toString());
while(!myStack.isEmpty()){
System.out.println(myStack.pop());
}
}
}
二、队列
FIFO:在队首出队,在队尾入队,先进先出的数据结构
食堂排队就是队列结构
1.基础队列的实现
1)基于数组实现的队列--顺序队列
2)基于链表实现的队列--链式队列(优)
由于队列是队尾入队,队首出队,队首出队如果用数组就是数组的头部删除,时间复杂度为O(n),此时使用链表会更好,在链表尾部插入,头部删除,或者尾删头插。

头删尾插举例:
/**
* 将队列设计为接口,泛型接口(支持多种类型)
* @param <E>
*/
public interface Queue<E> {
//入队
void offer(E val);
//出队
E poll();
//返回队首元素
E peek();
//队列是否为空
boolean isEmpty();
}
实现接口:
import java_1_24.stack_queue.queue.Queue;
import java.util.NoSuchElementException;
/**
* 队列的实现
* 基于链表实现的基础队列
*/
public class MyQueue<E> implements Queue<E> {
//节点--用成员内部类-链表的每个节点
private class Node{
E val;
Node next;
public Node(E val) {
this.val = val;
}
}
//当前队列元素个数
private int size;
//链表队首
private Node head;
//队尾
private Node tail;
//入队-尾插
@Override
public void offer(E val) {
Node node=new Node(val);
if(head==null){
//此时队列为空(头节点都为空尾也肯定为空)
head=
本文详细介绍了栈和队列这两种数据结构,包括它们的应用场景、实现方式以及常见操作。栈作为后进先出(LIFO)的数据结构,常用于撤销操作、浏览器历史记录等。队列则遵循先进先出(FIFO)原则,常用于任务调度。文中还讲解了循环队列的概念和判断满队列的条件,并通过LeetCode题目展示了如何用栈实现队列和队列实现栈。此外,文章还探讨了括号匹配问题和最小栈等栈的应用。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



