线性表之队列
主要内容
- 队列
一.队列
队列是一种先进先出(FIFO,First In First Out)的线性数据结构,它具有两个基本操作:入队(enqueue)和出(dequeue)。入队操作在队列的末尾添加一个元素,出队操作从队列的头部移除一个元素。
1.队列的顺序存储
代码如下(示例):
队列的顺序存储结构通常使用数组来实现,可以通过数组的下标来表示队列的头部和尾部,以及元素的添加和移除。下面是队列的顺序存储结构的示例代码:
C语言实现:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 定义队列结构
typedef struct {
int data[MAX_SIZE];
int front; // 队头指针
int rear; // 队尾指针
} Queue;
// 初始化队列
void initQueue(Queue *queue) {
queue->front = 0;
queue->rear = 0;
}
// 判断队列是否为空
int isEmpty(Queue *queue) {
return queue->front == queue->rear;
}
// 入队
void enqueue(Queue *queue, int value) {
if ((queue->rear + 1) % MAX_SIZE == queue->front) {
printf("Queue is full\n");
return;
}
queue->data[queue->rear] = value;
queue->rear = (queue->rear + 1) % MAX_SIZE;
}
// 出队
int dequeue(Queue *queue) {
if (isEmpty(queue)) {
printf("Queue is empty\n");
return -1;
}
int value = queue->data[queue->front];
queue->front = (queue->front + 1) % MAX_SIZE;
return value;
}
int main() {
Queue queue;
initQueue(&queue);
enqueue(&queue, 1);
enqueue(&queue, 2);
enqueue(&queue, 3);
printf("Dequeued: %d\n", dequeue(&queue));
printf("Dequeued: %d\n", dequeue(&queue));
printf("Dequeued: %d\n", dequeue(&queue));
return 0;
}
在这个示例中,我们使用了一个数组来存储队列的元素,
同时使用front和rear指针来表示队列的头部和尾部。
enqueue函数用于将元素添加到队列中,dequeue函数用于从队列中移除元素。
通过这种方式,我们可以使用数组来实现队列的顺序存储结构。
Python实现:
class ArrayQueue:
def __init__(self, capacity):
self.capacity = capacity
self.queue = [None] * capacity
self.front = 0
self.rear = 0
def enqueue(self, item):
if (self.rear + 1) % self.capacity == self.front:
raise Exception("Queue is full")
self.queue[self.rear] = item
self.rear = (self.rear + 1) % self.capacity
def dequeue(self):
if self.front == self.rear:
raise Exception("Queue is empty")
item = self.queue[self.front]
self.front = (self.front + 1) % self.capacity
return item
2.队列的链式存储
队列的链式存储结构通常使用链表来实现,每个节点表示队列中的一个元素,通过指针来连接各个节点。下面是队列的链式存储结构的示例代码:
C语言实现:
typedef struct QueueNode {
int data; // 队列中的元素
struct QueueNode *next; // 指向下一个节点的指针
} QueueNode;
typedef struct {
QueueNode *front; // 指向队头节点的指针
QueueNode *rear; // 指向队尾节点的指针
} Queue;
其中,
QueueNode
表示队列中的一个节点,包含一个data
成员表示节点中存储的元素,以及一个next
成员表示指向下一个节点的指针。
Queue
表示队列本身,包含两个指针成员front
和rear
,分别指向队头和队尾节点。
创建一个空队列可以用如下的代码:
Queue *createQueue() {
Queue *q = (Queue *)malloc(sizeof(Queue));
q->front = q->rear = NULL;
return q;
}
入队操作可以用如下的代码实现:
void enqueue(Queue *q, int data) {
QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode));
newNode->data = data;
newNode->next = NULL;
if (q->rear == NULL) {
q->front = q->rear = newNode;
} else {
q->rear->next = newNode;
q->rear = newNode;
}
}
出队操作可以用如下的代码实现:
int dequeue(Queue *q) {
if (q->front == NULL) {
printf("Queue is empty.\n");
return -1;
}
int data = q->front->data;
QueueNode *temp = q->front;
q->front = q->front->next;
free(temp);
if (q->front == NULL) {
q->rear = NULL;
}
return data;
}
需要注意的是,当队列为空时进行出队操作会导致错误,
因此在出队操作前需要先检查队列是否为空。
Python实现:
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedQueue:
def __init__(self):
self.front = None
self.rear = None
def enqueue(self, item):
new_node = Node(item)
if self.rear is None:
self.front = new_node
self.rear = new_node
else:
self.rear.next = new_node
self.rear = new_node
def dequeue(self):
if self.front is None:
raise Exception("Queue is empty")
item = self.front.data
self.front = self.front.next
if self.front is None:
self.rear = None
return item
3.双端队列
双端队列(deque)是一种具有队列和栈特性的数据结构,可以在队列的两端进行插入和删除操作。双端队列受限于元素的插入和删除操作只能在两端进行,不能在中间进行。
双端队列的相关示例包括:浏览器的前进和后退功能、打印机的打印任务队列等。
C语言示例:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int front, rear;
} Deque;
void initDeque(Deque *deque) {
deque->front = 0;
deque->rear = -1;
}
bool isFull(Deque *deque) {
return (deque->rear == MAX_SIZE - 1) || (deque->front == 0 && deque->rear == MAX_SIZE - 1);
}
bool isEmpty(Deque *deque) {
return (deque->front > deque->rear);
}
void insertFront(Deque *deque, int value) {
if (isFull(deque)) {
printf("Deque is full\n");
return;
}
deque->data[--deque->front] = value;
}
void insertRear(Deque *deque, int value) {
if (isFull(deque)) {
printf("Deque is full\n");
return;
}
deque->data[++deque->rear] = value;
}
int deleteFront(Deque *deque) {
if (isEmpty(deque)) {
printf("Deque is empty\n");
return -1;
}
return deque->data[deque->front++];
}
int deleteRear(Deque *deque) {
if (isEmpty(deque)) {
printf("Deque is empty\n");
return -1;
}
return deque->data[deque->rear--];
}
int main() {
Deque deque;
initDeque(&deque);
insertFront(&deque, 1);
insertRear(&deque, 2);
insertFront(&deque, 3);
insertRear(&deque, 4);
printf("Deleted from front: %d\n", deleteFront(&deque));
printf("Deleted from rear: %d\n", deleteRear(&deque));
return 0;
}
Python示例:
from collections import deque
deque = deque()
deque.appendleft(1)
deque.append(2)
deque.appendleft(3)
deque.append(4)
print("Deleted from front:", deque.popleft())
print("Deleted from rear:", deque.pop())
总结
以上是今天要讲的内容,学到了队列相关知识。