• 数据结构之队列(Queue)


    目录

    1.队列(Queue)之概念

    2.队列(Queue)之模拟实现

    3.队列(Queue)之使用

    4.队列(Queue)之循环队列

    5.队列(Queue)之双端队列(Deque)

    6.力扣中的练习题

    6.1 用队列实现栈

    6.2 用栈实现队列

    6.3 最小栈


    1.队列(Queue)之概念

    定义:队列是一种特殊的线性表,它只允许在一端进行插入(队尾)数据操作,在另一端进行删除(队头)数据操作。

    队列具有先进先出的特点

    队列的实现也是有两种方式

    数组实现,链表实现


    2.队列(Queue)之模拟实现

    以单链表实现,并且做一点改动

     先写一个上面这样结构的单链表

    1. static class Node {
    2. public int val;
    3. public Node next;
    4. public Node(int val) {
    5. this.val = val;
    6. }
    7. }
    8. public Node head;//队列头
    9. public Node tail;//队列尾

    (1)入队offer()

    1. public void offer(int val) {
    2. Node node = new Node(val);
    3. if (head == null) {
    4. head = node;
    5. tail = node;
    6. }else {
    7. tail.next = node;
    8. tail = tail.next;
    9. }
    10. }

    (2)出队poll()

    1. public int poll() {
    2. if(head == null) {
    3. return -1;
    4. }
    5. int oldVal = head.val;
    6. if (head.next == null) {
    7. head = tail = null;
    8. }else {
    9. head = head.next;
    10. }
    11. return oldVal;
    12. }

    (3)查看当前对头元素peek()

    1. public int peek() {
    2. if(head == null) {
    3. return -1;
    4. }
    5. return head.val;
    6. }

    3.队列(Queue)之使用

    1. public static void main(String[] args) {
    2. java.util.Queue queue = new LinkedList<>();
    3. queue.offer(1);
    4. queue.offer(5);
    5. queue.offer(7);
    6. queue.offer(45);
    7. System.out.println(queue.size());
    8. System.out.println(queue.peek());
    9. queue.poll();
    10. System.out.println(queue.poll());
    11. }

     

    4.队列(Queue)之循环队列

    先看顺序队列中元素的入队出队操作,因为队列元素出队是在对头,

    那也就是,队列中所有元素的移动都是在向前移动,而这样向前移动就会出现这样的问题

     所以,相对来说 对于队列最好的方法是使用链表实现,否则就会造成假溢出

    那么java中对于假溢出解决的办法是使用循环队列

    正常情况下,顺序队列中会发生假溢出,也就是开辟的数组空间还有剩余空间,却因为rear越界表现为溢出,

    使用循环队列,就是将队列的首尾相连,这样rear移动到LENGTH时,就会再从0开始循环

    1. 那么如何区分队列的空与满 因为当rear== front时,既表示空又表示满

     (1)最直接的方法就是计数

    (2)牺牲一个存储空间 front前面不存数据,当rear在front前面的时候就是满了(尾在头前就是满了)

    (3) 是设置一个标志变量flag,当front == rear,且flag = 0时为队列空,当front == rear,且flag= 1时为队列满

     看一个练习题

    链接622. 设计循环队列 - 力扣(LeetCode)

    题目要求  分析一下

    入队和出队除了要考虑队满和队空的条件,还要考虑,当这一圈转完,到下一圈,不能时不能只加加,还要模个数组长度,得出第二圈的下标

    上代码

    1. class MyCircularQueue {
    2. public int[] elem;
    3. public int front;//队头下标
    4. public int rear;//队尾下标
    5. public MyCircularQueue(int k) {
    6. this.elem = new int[k+1];
    7. }
    8. //入队
    9. public boolean enQueue(int value) {
    10. if (isFull()) {
    11. return false;
    12. }
    13. this.elem[rear] = value;
    14. rear = (rear+1) % elem.length;
    15. return true;
    16. }
    17. //出队
    18. public boolean deQueue() {
    19. if (isEmpty()) {
    20. return false;
    21. }
    22. front = (front+1) % elem.length;//如果是K到0那就要%
    23. return true;
    24. }
    25. //从队首获取元素
    26. public int Front() {
    27. if (isEmpty()) {
    28. return -1;
    29. }
    30. return elem[front];
    31. }
    32. //获取队尾元素
    33. public int Rear() {
    34. if (isEmpty()) {
    35. return -1;
    36. }
    37. int index = (rear == 0) ? elem.length-1 : rear-1;
    38. return elem[index];
    39. }
    40. public boolean isEmpty() {
    41. return rear == front;
    42. }
    43. public boolean isFull() {
    44. return (rear+1) % elem.length == front;
    45. }
    46. }

     

    5.队列(Queue)之双端队列(Deque)

    双端队列(Deque)是指在两端都可以进行入队和出队的操作的队列

    不过需要注意的是,不能将一个数据,在一端进行入队和出队操作,不然这样就成了栈

     

     Deque是一个接口,使用时必须要创建LinkedList的对象

            Deque myQueue2 = new LinkedList<>();

    6.力扣中的练习题

    6.1 用队列实现栈

    链接  225. 用队列实现栈 - 力扣(LeetCode)

    题目要求

     分析一下

     

     上代码

    1. class MyStack {
    2. Queue qu1;
    3. Queue qu2;
    4. public int usedSize;
    5. public MyStack() {
    6. qu1 = new LinkedList<>();
    7. qu2 = new LinkedList<>();
    8. }
    9. public void push(int x) {
    10. if(!qu1.isEmpty()) {
    11. qu1.offer(x);
    12. } else if(!qu2.isEmpty()) {
    13. qu2.offer(x);
    14. } else {
    15. qu1.offer(x);
    16. }
    17. usedSize++;
    18. }
    19. public int pop() {
    20. if(empty()) {
    21. return -1;
    22. }
    23. if(!qu1.isEmpty()) {
    24. int curSize = qu1.size();
    25. for(int i = 0; i < curSize-1; i++) {
    26. qu2.offer(qu1.poll());
    27. }
    28. usedSize--;
    29. return qu1.poll();
    30. }else {
    31. int curSize = qu2.size();
    32. for(int i = 0; i < curSize-1; i++) {
    33. qu1.offer(qu2.poll());
    34. }
    35. usedSize--;
    36. return qu2.poll();
    37. }
    38. }
    39. public int top() {
    40. if(empty()) {
    41. return -1;
    42. }
    43. if(!qu1.isEmpty()) {
    44. int curSize = qu1.size();
    45. int ret = -1;
    46. for(int i = 0; i < curSize; i++) {
    47. ret = qu1.poll();
    48. qu2.offer(ret);
    49. }
    50. return ret;
    51. }else {
    52. int curSize = qu2.size();
    53. int ret = -1;
    54. for(int i = 0; i < curSize; i++) {
    55. ret = qu2.poll();
    56. qu1.offer(ret);
    57. }
    58. return ret;
    59. }
    60. }
    61. public boolean empty() {
    62. return usedSize == 0;
    63. }
    64. }

     

    6.2 用栈实现队列

    链接  232. 用栈实现队列 - 力扣(LeetCode)

    题目要求

     分析一下

     上代码

    1. class MyQueue {
    2. Stack s1;
    3. Stack s2;
    4. public MyQueue() {
    5. s1 = new Stack<>();
    6. s2 = new Stack<>();
    7. }
    8. public void push(int x) {
    9. s1.push(x);
    10. }
    11. public int pop() {
    12. if(empty()) {
    13. return -1;
    14. }
    15. if(s2.empty()) {
    16. //将s1中所有元素倒过来
    17. while(!s1.empty()) {
    18. s2.push(s1.pop());
    19. }
    20. }
    21. return s2.pop();
    22. }
    23. public int peek() {
    24. if(empty()) {
    25. return -1;
    26. }
    27. if(s2.empty()) {
    28. //将s1中所有元素倒过来
    29. while(!s1.empty()) {
    30. s2.push(s1.pop());
    31. }
    32. }
    33. return s2.peek();
    34. }
    35. public boolean empty() {
    36. return s1.empty() && s2.empty();
    37. }
    38. }

    6.3 最小栈

    链接  155. 最小栈 - 力扣(LeetCode)

    题目要求

    分析一下

     上代码

    1. class MinStack {
    2. private Stack s;//普通栈
    3. private Stack minStack;//最小栈
    4. public MinStack() {
    5. s = new Stack<>();
    6. minStack = new Stack<>();
    7. }
    8. public void push(int val) {
    9. s.push(val);
    10. if(minStack.empty()) {
    11. //最小栈为null,直接放
    12. minStack.push(val);
    13. }else {
    14. int peekV = minStack.peek();
    15. if(val <= peekV) {
    16. minStack.push(val);
    17. }
    18. }
    19. }
    20. public void pop() {
    21. int popV = s.pop();
    22. int peekVMinS = minStack.peek();
    23. if(popV == peekVMinS) {
    24. minStack.pop();
    25. }
    26. }
    27. public int top() {
    28. return s.peek();
    29. }
    30. public int getMin() {
    31. return minStack.peek();
    32. }
    33. }

  • 相关阅读:
    机器学习(十八)应用实例:照片OCR
    oracle临时表 WITH AS用法
    RocketMQ
    【AVL树】
    [附源码]SSM计算机毕业设计疫情防控期间人员档案追寻系统JAVA
    【踩坑】工作中真实踩坑,一个or让sql变慢7倍
    【脑机接口】POINT疗法或将为卒中后失语患者带来新希望!
    Java dom4j如何获取,添加,删除,查找,设置Element属性呢?
    layui tree监控选中事件,同步选中和取消
    踩坑日记 《正确的使用Vuex》基于 uniapp Vue3 setup 语法糖 vuex4 项目 太多坑了要吐了
  • 原文地址:https://blog.csdn.net/m0_58761900/article/details/125705021