📅  最后修改于: 2023-12-03 15:26:09.297000             🧑  作者: Mango
队列是一种基本的数据结构,它具有先进先出(FIFO)的特点。在队列中,元素只会在队列的一端(称为队尾)添加,而在另一端(称为队头)删除。队列的链表实现是一种常见的实现方式。
队列的基本操作包括入队和出队两个操作:
此外,队列还有两个基本属性:
队列的链表实现是一种基于链表的实现方式,它的数据结构类似于链表。每个节点包含两个指针,一个指向该节点的数据,一个指向下一个节点。头节点指向队头,尾节点指向队尾。
为了实现队列的链表实现,我们需要定义节点和队列两个数据结构。我们可以使用结构体来定义这两个数据结构。
/**
* 队列节点结构体
*/
typedef struct QueueNode {
void *data; // 指向节点数据的指针
struct QueueNode *next; // 指向下一个节点的指针
} QueueNode;
/**
* 队列结构体
*/
typedef struct Queue {
QueueNode *head; // 指向队头节点的指针
QueueNode *tail; // 指向队尾节点的指针
int size; // 队列中元素的数量
int capacity; // 队列的最大容量
} Queue;
在使用队列之前,我们需要先初始化队列。初始化队列时,我们需要为队列分配内存,并将队列的头和尾都初始化为 NULL
。
/**
* 初始化队列
* @param queue 队列指针
* @param capacity 队列的最大容量
*/
void queue_init(Queue *queue, int capacity) {
queue->head = NULL;
queue->tail = NULL;
queue->size = 0;
queue->capacity = capacity;
}
队列的入队操作是向队列的尾部添加一个元素。为了实现入队操作,我们需要先创建一个新的节点,并将该节点的 data
指针指向要添加的元素。然后,我们将新的节点添加到队列的尾部,并更新队列的 size
属性。
/**
* 入队操作
* @param queue 队列指针
* @param data 要入队的数据
* @return 返回操作结果。如果入队成功,返回 0;否则返回 -1。
*/
int queue_enqueue(Queue *queue, void *data) {
// 如果队列已满,返回错误
if (queue->size == queue->capacity) {
return -1;
}
// 创建新节点
QueueNode *node = (QueueNode *) malloc(sizeof(QueueNode));
node->data = data;
node->next = NULL;
// 如果队列为空,将头尾指向新节点
if (queue->size == 0) {
queue->head = node;
queue->tail = node;
} else {
// 将新节点添加到队列尾部,更新队列尾指针
queue->tail->next = node;
queue->tail = node;
}
// 更新队列元素数量
queue->size++;
return 0;
}
队列的出队操作是从队列的头部删除一个元素。为了实现出队操作,我们需要先获取队列头部的元素,然后将队列头部的节点删除,并将该节点的 data
指针返回。
/**
* 出队操作
* @param queue 队列指针
* @return 返回队列头部的数据。如果队列为空,返回 NULL。
*/
void *queue_dequeue(Queue *queue) {
// 如果队列为空,返回 NULL
if (queue->size == 0) {
return NULL;
}
// 获取队列头部节点的数据
QueueNode *node = queue->head;
void *data = node->data;
// 更新队列头指针,并释放节点内存
queue->head = node->next;
free(node);
// 更新队列元素数量
queue->size--;
return data;
}
我们可以通过以下函数查询队列的状态:
/**
* 查询队列元素数量
* @param queue 队列指针
* @return 返回队列中元素的数量
*/
int queue_size(Queue *queue) {
return queue->size;
}
/**
* 查询队列容量
* @param queue 队列指针
* @return 返回队列的容量
*/
int queue_capacity(Queue *queue) {
return queue->capacity;
}
/**
* 查询队列是否为空
* @param queue 队列指针
* @return 如果队列为空,返回 1;否则返回 0。
*/
int queue_is_empty(Queue *queue) {
return queue->size == 0;
}
/**
* 查询队列是否已满
* @param queue 队列指针
* @return 如果队列已满,返回 1;否则返回 0。
*/
int queue_is_full(Queue *queue) {
return queue->size == queue->capacity;
}
队列的链表实现是一种基于链表的实现方式,它的数据结构类似于链表。每个节点包含两个指针,一个指向该节点的数据,一个指向下一个节点。头节点指向队头,尾节点指向队尾。队列的基本操作包括入队和出队两个操作,此外,队列还有两个基本属性:队列长度和队列空间。队列的链表实现可以在不限制队列长度的情况下使用。