• 队列(Queue)的详解


         队列:只允许在一端进行插入操作,在另一端进行删除数据操作的特殊的线性表,队列具有先进先出

    1、入队列:进行插入操作的一端称为队尾(Tail/Rear)

          出队列:进行删除操作的一端称为对头(Head/Front)

    2、队列的使用

          在Java中,Queue是个接口,底层是通过链表实现的

    注:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。

    以下代码为Queue的代码演示

    1. import java.util.LinkedList;
    2. import java.util.Queue;
    3. //Queue 的演示示例
    4. public class Demo2 {
    5. public static void main(String[] args) {
    6. Queue queue = new LinkedList<>();
    7. System.out.println(queue.size());
    8. System.out.println(queue);
    9. System.out.println("===============================");
    10. //出队
    11. queue.poll();
    12. System.out.println(queue.peek());
    13. System.out.println(queue);
    14. System.out.println("===============================");
    15. // //删除,没有元素的时候会抛出异常
    16. // System.out.println(queue.remove());
    17. // System.out.println(queue);
    18. // System.out.println(queue);
    19. // //获取,没有元素的时候会抛出异常
    20. // System.out.println(queue.element());
    21. // System.out.println(queue);
    22. }
    23. public static void main1(String[] args) {
    24. Queue queue = new LinkedList<>();
    25. //入队
    26. queue.offer(1);
    27. queue.offer(2);
    28. queue.offer(3);
    29. queue.offer(4);
    30. queue.offer(5);
    31. System.out.println(queue.size());
    32. System.out.println(queue);
    33. System.out.println("===============================");
    34. //出队
    35. queue.poll();
    36. System.out.println(queue.peek());
    37. System.out.println(queue);
    38. System.out.println("===============================");
    39. //删除
    40. System.out.println(queue.remove());
    41. System.out.println(queue);
    42. System.out.println(queue.remove(5));
    43. System.out.println(queue);
    44. //获取
    45. System.out.println(queue.element());
    46. System.out.println(queue);
    47. }
    48. }

    3、队列的模拟实现

    1. //用双向链表实现
    2. public class MyQueue {
    3. private static class ListNode {
    4. int val;
    5. ListNode prev;
    6. ListNode next;
    7. public ListNode(int val) {
    8. this.val = val;
    9. }
    10. }
    11. private ListNode head;
    12. private ListNode tail;
    13. public int size;
    14. public void offer (int e){
    15. ListNode node = new ListNode(e);
    16. if(head == null) {
    17. head = node;
    18. } else {
    19. tail.next = node;
    20. node.prev = tail;
    21. }
    22. tail = node;
    23. size++;
    24. }
    25. public int poll (){
    26. if(isEmpty()) {
    27. throw new RuntimeException("队列为空");
    28. }
    29. int headValue = head.val;
    30. head = head.next;
    31. if(head == null) {
    32. tail = null;
    33. } else {
    34. head.prev.next = null;
    35. head.prev = null;
    36. }
    37. size--;
    38. return headValue;
    39. }
    40. public int peek(){
    41. if(isEmpty()) {
    42. throw new RuntimeException("队列为空");
    43. }
    44. return head.val;
    45. }
    46. public int size (){
    47. return -1;
    48. }
    49. public boolean isEmpty() {
    50. return size == 0;
    51. }
    52. public void display(){
    53. ListNode cur = head;
    54. StringBuilder sb = new StringBuilder();
    55. sb.append("[");
    56. while(cur != null){
    57. sb.append(cur.val);
    58. if(cur.next != null){
    59. sb.append(",");
    60. }
    61. cur = cur.next;
    62. }
    63. sb.append("]");
    64. System.out.println(sb.toString());
    65. }
    66. }

     4、循环队列

           环形队列通常使用数组实现

    注意:

          底层还是一个数组,指定一个队列的大小,入队时,当队列满的时候就不能再放了,出队时当队列为空的时候就不能再出队了 

          加一个冗余位置,当rear = front + 1这时,可以判定队列已满

          改变下标位置:(index + x)% array.length = 正确的下标

    以下代码设计循环队列

    1. class MyCircularQueue {
    2. private int[] elementData;
    3. private int front;
    4. private int rear;
    5. public MyCircularQueue(int k) {
    6. this.elementData = new int[k + 1];
    7. }
    8. //入队
    9. public boolean enQueue(int value) {
    10. if(isFull()) {
    11. return false;
    12. }
    13. elementData[rear] = value;
    14. rear = (rear + 1) % elementData.length;
    15. return true;
    16. }
    17. //出队
    18. public boolean deQueue() {
    19. if(isEmpty()) {
    20. return false;
    21. }
    22. // int res = elementData[front];出队的值
    23. front = (front + 1) % elementData.length;
    24. return true;
    25. }
    26. //取队首元素
    27. public int Front() {
    28. if(isEmpty()) {
    29. return -1;//在oj题不要抛异常,return-1即可
    30. }
    31. return elementData[front];
    32. }
    33. //取队尾元素
    34. public int Rear() {
    35. if(isEmpty()) {
    36. return -1;
    37. }
    38. return elementData[(rear - 1 + elementData.length) % elementData.length];
    39. }
    40. public boolean isEmpty() {
    41. return rear == front;
    42. }
    43. //判断是否已满
    44. public boolean isFull() {
    45. return (rear + 1) % elementData.length == front;
    46. }
    47. }

    5、双端队列(Deque)

         双端队列是指允许两端都可以进行入队和出队的操作的队列,Deque是一个接口,使用时必须创建LinkedList的对象

    注意:栈,在Java中是用数组实现的,Stack继承自Vector,性质是后进先出 LIFO

              队列,在Java中是用双向链表实现的,实现类是LinkedList,性质是先进先出 FIFO 

  • 相关阅读:
    【无标题】
    新火种AI|Claude 3.5一夜封王超越GPT-4o!留给OpenAI的时间真的不多了...
    能解决 80% 故障的排查思路
    JAVA计算机毕业设计高校毕业生就业满意度调查统计系统Mybatis+源码+数据库+lw文档+系统+调试部署
    基于libcurl+libopenssl开源库编译出curl下载工具及代码集成curl功能
    零基础学习CANoe Panel(1)—— 新建 Panel
    java多态、重载、构造函数及析构函数介绍
    遗传算法GA求解TSP问题
    docker镜像升级python3.5→python3.9(Ubuntu)
    DTD和XSD的区别
  • 原文地址:https://blog.csdn.net/m0_53677355/article/details/127482215