# 队列

> 原文： [https://www.programiz.com/dsa/queue](https://www.programiz.com/dsa/queue)

#### 在本教程中，您将学习什么是队列。 此外，您还将发现使用 C，C++ ，Java 和 Python 实现队列的实现。

队列是编程中有用的数据结构。 它类似于电影院大厅外面的售票队列，在该队列中，第一个进入队列的人是第一个获得票的人。

队列遵循**先进先出（FIFO）**规则-先进入的项目也是先出来的项目。

![queue first in first out diagram](img/ee40d5ecf1e9d1f65fb5588ea32c5051.png "Queue")

FIFO 表示



在上图中，由于 1 在 2 之前保留在队列中，因此它也是第一个从队列中删除的队列。 它遵循 **FIFO** 规则。

用编程术语来说，将项目放入队列称为“入队”，而将项目从队列中删除则称为“出队”。

我们可以使用任何编程语言（例如 C，C++ ，Java，Python 或 C# ）来实现队列，但是规范几乎是相同的。

* * *

## 队列规范

队列是一个对象，或更具体地说，是一个允许执行以下操作的抽象数据结构（ADT）：

*   `enqueue`：将元素添加到队列的末尾
*   `dequeue`：从队列的开头删除元素
*   **`IsEmpty`**：检查队列是否为空
*   **`IsFull`**：检查队列是否已满
*   `peek`：获取队列前面的值而不删除它

* * *

## 队列如何工作

队列操作如下：

1.  两个称为`FRONT`和`REAR`的指针用于跟踪队列中的第一个和最后一个元素。
2.  初始化队列时，我们将`FRONT`和`REAR`的值设置为 -1。
3.  排队元素时，我们增加`REAR`索引的值，并将新元素放置在`REAR`指向的位置。
4.  在元素出队时，我们返回`FRONT`指向的值，并增加`FRONT`索引。
5.  在排队之前，我们检查队列是否已满。
6.  在出队之前，我们检查队列是否已经为空。
7.  当对第一个元素进行排队时，我们将`FRONT`的值设置为 0。
8.  使最后一个元素出队时，我们将`FRONT`和`REAR`的值重置为 -1。

![Demonstrating how front and rear indexes are modified during enqueue and dequeue operations](img/839247f58959fe9eff35f88034788ae4.png "Working of queue operations")

队列操作的原理



* * *

## Python，Java 和 C/C++ 示例

最常见的队列实现是使用数组，但是也可以使用列表来实现。



```py
# Queue implementation in Python

class Queue:

    def __init__(self):
        self.queue = []

    # Add an element
    def enqueue(self, item):
        self.queue.append(item)

    # Remove an element
    def dequeue(self):
        if len(self.queue) < 1:
            return None
        return self.queue.pop(0)

    # Display  the queue
    def display(self):
        print(self.queue)

    def size(self):
        return len(self.queue)

q = Queue()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
q.enqueue(4)
q.enqueue(5)

q.display()

q.dequeue()

print("After removing an element")
q.display() 
```

```java
// Queue implementation in Java

public class Queue {
  int SIZE = 5;
  int items[] = new int[SIZE];
  int front, rear;

  Queue() {
    front = -1;
    rear = -1;
  }

  boolean isFull() {
    if (front == 0 && rear == SIZE - 1) {
      return true;
    }
    return false;
  }

  boolean isEmpty() {
    if (front == -1)
      return true;
    else
      return false;
  }

  void enQueue(int element) {
    if (isFull()) {
      System.out.println("Queue is full");
    } else {
      if (front == -1)
        front = 0;
      rear++;
      items[rear] = element;
      System.out.println("Inserted " + element);
    }
  }

  int deQueue() {
    int element;
    if (isEmpty()) {
      System.out.println("Queue is empty");
      return (-1);
    } else {
      element = items[front];
      if (front >= rear) {
        front = -1;
        rear = -1;
      } /* Q has only one element, so we reset the queue after deleting it. */
      else {
        front++;
      }
      System.out.println("Deleted -> " + element);
      return (element);
    }
  }

  void display() {
    /* Function to display elements of Queue */
    int i;
    if (isEmpty()) {
      System.out.println("Empty Queue");
    } else {
      System.out.println("\nFront index-> " + front);
      System.out.println("Items -> ");
      for (i = front; i <= rear; i++)
        System.out.print(items[i] + "  ");

      System.out.println("\nRear index-> " + rear);
    }
  }

  public static void main(String[] args) {
    Queue q = new Queue();

    // deQueue is not possible on empty queue
    q.deQueue();

    // enQueue 5 elements
    q.enQueue(1);
    q.enQueue(2);
    q.enQueue(3);
    q.enQueue(4);
    q.enQueue(5);

    // 6th element can't be added to queue because queue is full
    q.enQueue(6);

    q.display();

    // deQueue removes element entered first i.e. 1
    q.deQueue();

    // Now we have just 4 elements
    q.display();

  }
}
```

```c
// Queue implementation in C

#include <stdio.h>
#define SIZE 5

void enQueue(int);
void deQueue();
void display();

int items[SIZE], front = -1, rear = -1;

int main() {
  //deQueue is not possible on empty queue
  deQueue();

  //enQueue 5 elements
  enQueue(1);
  enQueue(2);
  enQueue(3);
  enQueue(4);
  enQueue(5);

  //6th element can't be added to queue because queue is full
  enQueue(6);

  display();

  //deQueue removes element entered first i.e. 1
  deQueue();

  //Now we have just 4 elements
  display();

  return 0;
}

void enQueue(int value) {
  if (rear == SIZE - 1)
    printf("\nQueue is Full!!");
  else {
    if (front == -1)
      front = 0;
    rear++;
    items[rear] = value;
    printf("\nInserted -> %d", value);
  }
}

void deQueue() {
  if (front == -1)
    printf("\nQueue is Empty!!");
  else {
    printf("\nDeleted : %d", items[front]);
    front++;
    if (front > rear)
      front = rear = -1;
  }
}

// Function to print the queue
void display() {
  if (rear == -1)
    printf("\nQueue is Empty!!!");
  else {
    int i;
    printf("\nQueue elements are:\n");
    for (i = front; i <= rear; i++)
      printf("%d  ", items[i]);
  }
  printf("\n");
}
```

```cpp
// Queue implementation in C++

#include <iostream>
#define SIZE 5

using namespace std;

class Queue {
   private:
  int items[SIZE], front, rear;

   public:
  Queue() {
    front = -1;
    rear = -1;
  }

  bool isFull() {
    if (front == 0 && rear == SIZE - 1) {
      return true;
    }
    return false;
  }

  bool isEmpty() {
    if (front == -1)
      return true;
    else
      return false;
  }

  void enQueue(int element) {
    if (isFull()) {
      cout << "Queue is full";
    } else {
      if (front == -1) front = 0;
      rear++;
      items[rear] = element;
      cout << endl
         << "Inserted " << element << endl;
    }
  }

  int deQueue() {
    int element;
    if (isEmpty()) {
      cout << "Queue is empty" << endl;
      return (-1);
    } else {
      element = items[front];
      if (front >= rear) {
        front = -1;
        rear = -1;
      } /* Q has only one element, so we reset the queue after deleting it. */
      else {
        front++;
      }
      cout << endl
         << "Deleted -> " << element << endl;
      return (element);
    }
  }

  void display() {
    /* Function to display elements of Queue */
    int i;
    if (isEmpty()) {
      cout << endl
         << "Empty Queue" << endl;
    } else {
      cout << endl
         << "Front index-> " << front;
      cout << endl
         << "Items -> ";
      for (i = front; i <= rear; i++)
        cout << items[i] << "  ";
      cout << endl
         << "Rear index-> " << rear << endl;
    }
  }
};

int main() {
  Queue q;

  //deQueue is not possible on empty queue
  q.deQueue();

  //enQueue 5 elements
  q.enQueue(1);
  q.enQueue(2);
  q.enQueue(3);
  q.enQueue(4);
  q.enQueue(5);

  //6th element can't be added to queue because queue is full
  q.enQueue(6);

  q.display();

  //deQueue removes element entered first i.e. 1
  q.deQueue();

  //Now we have just 4 elements
  q.display();

  return 0;
}
```

* * *

## 此实现的局限性

如您在下图中所看到的，经过一些入队和出队后，队列的大小已减小。

![size of queue reduced after enqueuing and dequeuing](img/0102c607330d976b4cd074f442b68f1a.png "Queue representation")

队列限制



只有当所有元素都已出队后，才能在重置队列后使用索引 0 和 1。

在`REAR`到达最后一个索引之后，如果我们可以在空白空间（0 和 1）中存储额外的元素，则可以利用这些空白空间。 这通过称为[循环队列](/data-structures/circular-queue)的修改队列来实现。

* * *

## 队列复杂度

使用数组的队列中入队和出队操作的复杂度为`O(1)`。

* * *

## 队列应用

*   CPU 调度，磁盘调度
*   在两个进程之间异步传输数据时，使用队列进行同步。 例如：IO 缓冲区，管道，文件 IO 等
*   实时系统中的中断处理。
*   呼叫中心电话系统使用队列来保持人们按顺序呼叫他们