文章目录
- 前言
- 一、栈是什么?
- 二、栈的使用
- 1.方法
- 2.代码实现
- 三.栈的模拟
- 四.队列
- 1.方法
- 2.代码实现
- 3.循环队列
- 4.双端队列
- 总结:
前言
今天,带你彻底理解栈和队列。
一、栈是什么?
栈英文叫做stack,是一种特殊的线性表。插入和删除的一端叫做栈顶,另一端叫做栈底,遵循后进先出的原则。
压栈:栈的插入操作。
出栈:栈的删除操作。
俩个操作都是在栈顶。
详情看图
二、栈的使用
1.方法
方法 功能
Stack() 构造一个空的栈
E push(E e) 将e入栈,并返回e
E pop() 将栈顶元素出栈并返回
E peek() 获取栈顶元素
int size() 获取栈中有效元素个数
boolean empty() 检测栈是否为空
2.代码实现
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());
}
}
**
三.栈的模拟
public class MyStack {
int[] array;
int size;
public MyStack(){
array = new int[3];
}
public int push(int e){
ensureCapacity();
array[size++] = e;
return e;
}
public int pop(){
int e = peek();
size--;
return e;
}
public int peek(){
if(empty()){
throw new RuntimeException("栈为空,无法获取栈顶元素");
}
return array[size-1];
}
public int size(){
return size;
}
public boolean empty(){
return 0 == size;
}
private void ensureCapacity(){
if(size == array.length){
array = Arrays.copyOf(array, size*2);
}
}
}
四.队列
队列:英文名是Queue,只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstIn First Out) 。
入队列:进行插入操作的一端称为队尾(Tail/Rear) 。
出队列:进行删除操作的一端称为队头。
Queue是个接口,底层是通过链表实现的。
1.方法
方法 功能
boolean offer(E e) 入队列
E poll() 出队列
peek() 获取队头元素
int size() 获取队列中有效元素个数
boolean isEmpty() 检测队列是否为空
2.代码实现
Queue<Integer> q = new LinkedList<>();
q.offer(10);
q.offer(20);
q.offer(30);
q.offer(40);
q.offer(50); // 从队尾入队列
System.out.println(q.size());//初始队列长度
System.out.println(q.peek()); // 获取队头元素
q.poll();
System.out.println(q.poll()); // 从队头出队列,并将删除的元素返回
if (q.isEmpty()) {
System.out.println("队列空");
} else {
System.out.println(q.size());//出队列后的长度
}
System.out.println(q);
3.循环队列
那又有什么方法可以从7跳到1讷:
可以用usedsize;
或者牺牲一个空间
//力扣622题原题牺牲一个空间的写法
class MyCircularQueue {
private int front;
private int rear;
private int capacity;
private int[] elements;
public MyCircularQueue(int k) {
capacity = k + 1;
elements = new int[capacity];
rear = front = 0;
}
public boolean enQueue(int value) {
if (isFull()) {
return false;
}
elements[rear] = value;
rear = (rear + 1) % capacity;
return true;
}
public boolean deQueue() {
if (isEmpty()) {
return false;
}
front = (front + 1) % capacity;
return true;
}
public int Front() {
if (isEmpty()) {
return -1;
}
return elements[front];
}
public int Rear() {
if (isEmpty()) {
return -1;
}
return elements[(rear - 1 + capacity) % capacity];
}
public boolean isEmpty() {
return rear == front;
}
public boolean isFull() {
return ((rear + 1) % capacity) == front;
}
}
/**
* Your MyCircularQueue object will be instantiated and called as such:
* MyCircularQueue obj = new MyCircularQueue(k);
* boolean param_1 = obj.enQueue(value);
* boolean param_2 = obj.deQueue();
* int param_3 = obj.Front();
* int param_4 = obj.Rear();
* boolean param_5 = obj.isEmpty();
* boolean param_6 = obj.isFull();
*/
4.双端队列
英文叫做Deque,deque 是 “double ended queue” 的简称。
是俩头可以进行入队和出队。
Deque是一个接口,使用时必须创建LinkedList的对象。
***注意:***deque是双端队列的链式实现。
Stack<Integer>stack = new Stack<>();
Deque<Integer>stack1 = new ArrayDeque<>();//一般情况下第二种的实现更好
因为本质上ArrayDeque也就是数组实现的。
总结:
好了,今天的博客到此为止了,欢迎大佬们的指正,希望三连!!😘😘😘😘