赞
踩
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。
队列的实现方式有多种,包括基于数组的实现和基于链表的实现。基于数组的实现可能需要处理数组的扩容问题,而基于链表的实现则相对灵活,但在某些情况下可能会浪费一些内存空间。
这里采用的是链表的方式实现的。
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
另外扩展了解一下,实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。
以下是队列的特点
实现队列的基本操作
用链表实现队列,因为更适合先进先出。
typedef int QDataType;
// 链式结构:表示队列
typedef struct QueueNode
{
struct QueueNode* next;
QDataType date;
}QNode;
结构体嵌套结构体指针,一个指向头,一个指向尾,一个记录长度。
// 队列的结构
typedef struct Queue
{
QNode* phead;//头
QNode* ptail;//尾
int size;
}Queue;
不初始化就是随机值。
//初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
避免出现野指针的错误。
//销毁 void QueueDestroy(Queue* pq) { assert(pq); QNode* cur = pq->phead; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->phead = NULL; pq->ptail = NULL; pq->size = 0; }
在队列的尾部插入一个元素。
//入队列 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode)); if (newnode == NULL) { perror("QueuePush"); return; } newnode->date = x; newnode->next = NULL; if (pq->ptail == NULL) { assert(pq->phead == NULL); pq->phead = pq->ptail = newnode; } else { pq->ptail->next = newnode; pq->ptail = newnode; } pq->size++; }
从队列的头部删除一个元素,并返回这个元素的值。
//出队 void QueuePop(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); //1个节点 if (pq->phead->next == NULL) { free(pq->phead); pq->phead = pq->ptail = NULL; } //多个节点 else { QNode* next = pq->phead->next; free(pq->phead); pq->phead = next; } pq->size--; }
返回队列头部元素的值,但不删除它。
//获取队头数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->phead->date;
}
返回队列尾部元素的值
//获取队尾数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->ptail->date;
}
返回队列中元素的数量。
//元素个数
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
如果队列中没有任何元素,返回true;否则返回false。
//判空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL
&& pq->ptail == NULL;
}
#define _CRT_SECURE_NO_WARNINGS 1 #include "Queue.h" void TestQueue() { Queue q; QueueInit(&q); QueuePush(&q, 3); QueuePush(&q, 4); QueuePush(&q, 5); printf("%d ", QueueFront(&q)); QueuePush(&q, 6); QueuePush(&q, 7); QueuePush(&q, 8); printf("size: %d ", QueueSize(&q)); printf("\n"); while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("\n"); QueueDestroy(&q); } int main() { TestQueue(); return 0; }
#define _CRT_SECURE_NO_WARNINGS 1 #include "Queue.h" //初始化 void QueueInit(Queue* pq) { assert(pq); pq->phead = NULL; pq->ptail = NULL; pq->size = 0; } //销毁 void QueueDestroy(Queue* pq) { assert(pq); QNode* cur = pq->phead; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->phead = NULL; pq->ptail = NULL; pq->size = 0; } //入队列 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode)); if (newnode == NULL) { perror("QueuePush"); return; } newnode->date = x; newnode->next = NULL; if (pq->ptail == NULL) { assert(pq->phead == NULL); pq->phead = pq->ptail = newnode; } else { pq->ptail->next = newnode; pq->ptail = newnode; } pq->size++; } //出队 void QueuePop(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); //1个节点 if (pq->phead->next == NULL) { free(pq->phead); pq->phead = pq->ptail = NULL; } //多个节点 else { QNode* next = pq->phead->next; free(pq->phead); pq->phead = next; } pq->size--; } //获取队头数据 QDataType QueueFront(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->phead->date; } //获取队尾数据 QDataType QueueBack(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->ptail->date; } //元素个数 int QueueSize(Queue* pq) { assert(pq); return pq->size; } //判空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->phead == NULL && pq->ptail == NULL; }
#pragma once #include <stdbool.h> #include <assert.h> #include <stdlib.h> #include <stdio.h> typedef int QDataType; // 链式结构:表示队列 typedef struct QueueNode { struct QueueNode* next; QDataType date; }QNode; // 队列的结构 typedef struct Queue { QNode* phead; QNode* ptail; int size; }Queue; //初始化 void QueueInit(Queue* pq); //销毁 void QueueDestroy(Queue* pq); //入队 void QueuePush(Queue* pq, QDataType x); //出队 void QueuePop(Queue* pq); //获取队头数据 QDataType QueueFront(Queue* pq); //获取队尾数据 QDataType QueueBack(Queue* pq); //元素个数 int QueueSize(Queue* pq); //判空 bool QueueEmpty(Queue* pq);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。