数据结构_栈和队列
栈和队列
- 一、栈
- 1.概念
- 2.栈的使用
- 3.栈的应用场景
- 二、队列
- 1. 队列的概念
- 2.循环队列
- 3.双端队列(Deque)
- 4. 经典题目
一、栈
1.概念
- 是一种特殊的线性表,仅允许在固定的一端(栈顶)进行插入和删除元素操作,另一端为栈底。
- 遵循**后进先出(LIFO,Last In First Out)**原则。
- 操作定义:
- 压栈/进栈/入栈:栈的插入操作,数据在栈顶进入。
- 出栈:栈的删除操作,数据从栈顶取出。
2.栈的使用
这是一段自定义栈结构的Java代码,包含了栈的核心操作方法,具体分析如下:
方法 | 功能 | 实现逻辑 |
---|---|---|
pop() | 弹出并返回栈顶元素 | 通过--top 先将栈顶指针减一,再获取对应位置的元素elem[--top] 并返回 |
peek() | 获取栈顶元素(不弹出) | 直接返回elem[top-1] ,即栈顶指针前一位的元素 |
size() | 获取栈中元素个数 | 返回栈顶指针top 的值,因为top 的数值就代表了栈中元素的数量 |
empty() | 清空栈 | 将栈顶指针top 置为0,从而实现栈的清空 |
栈的模拟实现
public class MyStack {int elem[];int top;public MyStack() {elem = new int[10];}//构造一个空栈private Boolean isFull() {if (top == elem.length) {return true;}return false;}private void grow(){elem= Arrays.copyOf(elem, elem.length*2);}//入栈public void push(int x) {if (isFull()) {grow();}elem[top++] = x;}//将栈顶元素取出并返回public int pop() {int x = elem[--top];return x;}//获取栈顶元素public int peek() {return elem[top-1];}//获取栈中有效元素public int size() {return top;}//检测栈是否为空public void empty() {top = 0;}
}
3.栈的应用场景
1.括号匹配
2.出栈入栈次序匹配题
3.逆波兰表达式求值
4.逆序打印链表:递归转循环的实现提取
递归方式
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<>();// 步骤1:将链表节点入栈Node cur = head;while(null != cur){s.push(cur);cur = cur.next;}// 步骤2:栈中元素出栈并打印(栈“后进先出”特性实现逆序)while(!s.empty()){System.out.print(s.pop().val + " ");}
}
原理:借助栈的“后进先出”特性,先将链表所有节点按顺序入栈,再依次出栈打印,从而实现逆序。
核心思路对比
实现方式 | 核心逻辑 | 优势 | 劣势 |
---|---|---|---|
递归 | 依赖方法调用栈的回溯 | 代码简洁 | 链表过长时可能栈溢出 |
循环(栈) | 显式用栈存储节点,再出栈打印 | 避免栈溢出风险,执行过程更可控 | 额外消耗栈的空间 |
5.设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素
二、队列
1. 队列的概念
队列是一种特殊的线性表,具有**先进先出(FIFO)**的特性。仅允许在一端(队尾,Tail/Rear)进行插入操作(入队,Enqueue),在另一端(队头,Head/Front)进行删除操作(出队,Dequeue)。
2.循环队列
循环队列通常使用数组实现
如何区分空和满
1.通过添加size属性纪录
2.保留一个位置
3.使用标记
设计循环队列
3.双端队列(Deque)
允许两端都可以进行入队和出队操作的队列.
Deque是一个接口使用时必须创建LinkList的对象
Deque 接口 :
可同时作为栈和队列使用,在实际工程中应用广泛。
• 实现示例: ◦ 线性实现:Deque stack = new ArrayDeque<>();(可作为栈使用)。
◦ 链式实现:Deque queue = new LinkedList<>();(可作为队列使用)。
4. 经典题目
1.用队列实现栈
2.用栈实现队列