栈(Stack)和队列(Deque、Queue)
文章目录
- 一、栈
- 1.1 栈 VS 虚拟机栈 VS 栈帧
- 1.2 数据结构 -- 栈介绍
- 1.3 用数组模拟实现栈
- 1.4 栈的功能:逆序打印
- 二、队列
- 2.1 数据结果 -- 队列介绍
- 2.2 用单链表模拟实现Queue队列
一、栈
1.1 栈 VS 虚拟机栈 VS 栈帧
- 区别:
- 栈:是一种数据结构
- 任何数据结构都是用来组织描述数据的
- 虚拟机栈(JVM虚拟机栈):是系统的一块内存
- 栈帧:方法调用的时候,在虚拟机栈上开辟的内存区域
- 栈:是一种数据结构
1.2 数据结构 – 栈介绍
- 栈的特点:只允许在固定的一端进行插入和删除元素操作,且是先进后出的
- Java中如何使用栈:
- Stack<类型> stack = new Stack<>();
- 上述方法用得越来越少了,现在多用【ArrayDequeue】代替
- 栈是如何实现的:
- 关于模拟实现栈:可以用数组/链表,Java中的Stack底层是用数组实现的
- 用数组实现:看下面
- 用链表实现
1.3 用数组模拟实现栈
- 实现结构:
- 此处设计是整型数组
- 使用usedSize记录当前有序的数据,插入元素时可以把它当成下标
- 添加元素 push():如果数组满了需要扩容
- 删除元素 pop():栈不为空时才出元素
- 获取栈顶元素 peek():栈不为空时才能获取
public class MyStack {
private int[] elem;
private int usedSize;
public MyStack() {
this.elem = new int[5];
}
//压栈 --- 放元素
public void push(int val) {
if(isFull()) {
elem = Arrays.copyOf(elem,2*elem.length);
}
elem[usedSize] = val;
usedSize++;
}
public boolean isFull() {
return usedSize == elem.length;
}
//出栈
public int pop() {
if(empty()) {
throw new StackEmptyException("栈为空!");
}
return elem[--usedSize];
}
//获取栈顶元素
public int peek() {
if(empty()) {
throw new StackEmptyException("栈为空!");
}
return elem[usedSize-1];
}
public boolean empty() {
return usedSize == 0;
}
}
//这是设计的自定义异常
public class StackEmptyException extends RuntimeException{
public StackEmptyException() {
}
public StackEmptyException(String message) {
super(message);
}
}
1.4 栈的功能:逆序打印
- 解析:如果我们要将一个递归实现的代码改成非递归,基本会用到栈/队列
- 代码:
二、队列
2.1 数据结果 – 队列介绍
-
队列特点:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,且是先进先出
-
Java中如何使用队列:
-
Deque 双端队列:
-
Queue 队列:
-
-
关于Queue队列的模拟实现:数组和链表都可以实现
-
用数组实现
-
用链表实现
-
2.2 用单链表模拟实现Queue队列
public class MyQueue {
public ListNode head;
public ListNode last;
static class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
private int usedSize;
public void offer(int val) {
ListNode node = new ListNode(val);
if(head == null) {
head = node;
last = node;
}else {
last.next = node;
last = last.next;
}
usedSize++;
}
public int getUsedSize() {
return usedSize;
}
public int poll() {
if(head == null) {
return -1;
}
int val = -1;
if(head.next == null) {
val = head.val;
head = null;
last = null;
return val;
}
val = head.val;
head = head.next;
usedSize--;
return val;
}
public int peek() {
if(head == null) {
return -1;
}
return head.val;
}
}