数据结构与算法-队列

什么是队列

 跟栈一样是一种操作受限的线性数据结构,满足先进先出的特性

顺序队列实现例子

 1 // 用数组实现的队列
 2 public class ArrayQueue {
 3   // 数组:items,数组大小:n
 4   private String[] items;
 5   private int n = 0;
 6   // head表示队头下标,tail表示队尾下标
 7   private int head = 0;
 8   private int tail = 0;
 9 
10   // 申请一个大小为capacity的数组
11   public ArrayQueue(int capacity) {
12     items = new String[capacity];
13     n = capacity;
14   }
15 
16   // 入队
17   public boolean enqueue(String item) {
18     // 如果tail == n 表示队列已经满了
19     if (tail == n) return false;
20     items[tail] = item;
21     ++tail;
22     return true;
23   }
24 
25   // 出队
26   public String dequeue() {
27     // 如果head == tail 表示队列为空
28     if (head == tail) return null;
29     // 为了让其他语言的同学看的更加明确,把--操作放到单独一行来写了
30     String ret = items[head];
31     ++head;
32     return ret;
33   }
34 }
View Code

基于链表的队列实现例子

需要两个指针:head 指针和 tail 指针。它们分别指向链表的第一个结点和最后一个结点。如图所示,入队时,tail->next= new_node, tail = tail->next;出队时,head = head->next

循环队列

用数组来实现队列的时候,在 tail==n 时,会有数据搬移操作,这样入队操作性能就会受到影响。那有没有办法能够避免数据搬移呢?我们来看看循环队列的解决思路。

这个队列的大小为 8,当前 head=4,tail=7。当有一个新的元素 a 入队时,我们放入下标为 7 的位置。但这个时候,我们并不把 tail 更新为 8,而是将其在环中后移一位,到下标为 0 的位置。当再有一个元素 b 入队时,我们将 b 放入下标为 0 的位置,然后 tail 加 1 更新为 1。所以,在 a,b 依次入队之后,循环队列中的元素就变成了下面的样子:

 当队列满了 tail始终会浪费一个节点数据

 

public class CircularQueue {
  // 数组:items,数组大小:n
  private String[] items;
  private int n = 0;
  // head表示队头下标,tail表示队尾下标
  private int head = 0;
  private int tail = 0;

  // 申请一个大小为capacity的数组
  public CircularQueue(int capacity) {
    items = new String[capacity];
    n = capacity;
  }

  // 入队
  public boolean enqueue(String item) {
    // 队列满了
    if ((tail + 1) % n == head) return false;
    items[tail] = item;
    tail = (tail + 1) % n;
    return true;
  }

  // 出队
  public String dequeue() {
    // 如果head == tail 表示队列为空
    if (head == tail) return null;
    String ret = items[head];
    head = (head + 1) % n;
    return ret;
  }
}
View Code

 

posted @ 2023-11-07 15:42  意犹未尽  阅读(11)  评论(0编辑  收藏  举报