1.队列
1.1队列的概念及结构
只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。即:先进先出
2.队列的实现
首先我们可以讨论一下,用数组实现好还是用队列实现好一些;
对于队列我们要进行入队和出队的操作,如果是使用数组来实现的话,那么我们所需要的时间开销就很大,需要不停的挪动数据。
但是反过来看链表的话,就方便了许多,不需要频繁的挪动数据,入队出队时的操作都显得相对容易和快速。
所以接下来我们将采用单链表的方式来实现队列。
2.1队列的实现
2.1.1声明
对于队列来说,我们采用单链表的形式来实现队列所以我们声明结构的形式和单链表几乎一样。一个区别队列这个为了方便入列出列,用了两个指针,一个用来指向头节点,另一个来指向尾节点。还有一个正整型变量用来记录队列的大小;
代码:
typedef int QdataType; typedef struct QueueNode { QdataType data; struct QueueNode* next; }QueueNode; typedef struct Queue { QueueNode* head; QueueNode* tail; size_t size; }Queue;
2.1.2初始化
void QueueInit(Queue* pq);
初始化也是非常的简单,就是将头指针和尾指针来置空,防止野指针的问题;
代码:
//队列的初始化 void QueueInit(Queue* pq) { assert(pq); pq->head = NULL; pq->tail = NULL; pq->size = 0; }
2.1.3队列的销毁
void QueueDestroy(Queue* pq);
对于队列的销毁,和单链表的销毁大同小异,都是从头开始一次进行free,代码实现不难;
代码:
//队列的销毁 void QueueDestroy(Queue* pq) { assert(pq); QueueNode* cur = pq->head; while (cur != NULL) { QueueNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; }
2.1.4入队列
入队列的话我们直接时进行一个尾插,但是我们这里采用的是无头的单链表,所以在这里我们要先判断一下,队列中是否有元素,如果有元素的话我们将头和尾都指向新插入的节点;
如果不是的话那就直接进行一个尾插
void QueuePush(Queue* pq, QdataType x);
代码:
//入队列 void QueuePush(Queue* pq, QdataType x) { assert(pq); QueueNode* NewNode = (QueueNode*)malloc(sizeof(QueueNode)); NewNode->next = NULL; NewNode->data = x; if (pq->head == NULL) { pq->head = NewNode; pq->tail = NewNode; } else { pq->tail->next = NewNode; pq->tail = NewNode; } }
2.1.5出队列
出队列的时候我们要注意一种情况就是是当队列中只剩一个节点的情况需要进行特殊的处理;因为剩余一个节点的时候我们和多个节点同样处理的话,就会产生尾节点是野指针的情况;
void QueuePop(Queue* pq);
代码:
//出队列 void QueuePop(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); //剩余一个节点的情况 if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QueueNode* del = pq->head; pq->head = pq->head->next; free(del); } }
2.1.6返回队列的首元素
这个函数没什么说的,唯一要注意的就是就要判断队列中是否还存在元素的情况,这个也可以非常的简单因为采用assert来判断就好了;
QdataType QueueFront(Queue* pq);
代码:
//返回队列的首元素 QdataType QueueFront(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->head->data; }
2.1.7判断队列是否为空
bool QueueEmpty(Queue* pq);
//判断队列是否为空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL && pq->tail == NULL; }
2.1.8计算队列中元素的数量
直接返回队列的size即可;相对于遍历整个队列的方法来说,效率更高;
int QueueSize(Queue* pq);
代码:
//队列的大小 int QueueSize(Queue* pq) { return pq->size; }
完整代码:
Quene.h:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h> typedef int QdataType; typedef struct QueueNode { QdataType data; struct QueueNode* next; }QueueNode; typedef struct Queue { QueueNode* head; QueueNode* tail; size_t 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);
Quene.c:
代码:
#define _CRT_SECURE_NO_WARNINGS 1 #include"Queue.h" //队列的初始化 void QueueInit(Queue* pq) { assert(pq); pq->head = NULL; pq->tail = NULL; pq->size = 0; } //队列的销毁 void QueueDestroy(Queue* pq) { assert(pq); QueueNode* cur = pq->head; while (cur != NULL) { QueueNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; } //入队列 void QueuePush(Queue* pq, QdataType x) { assert(pq); QueueNode* NewNode = (QueueNode*)malloc(sizeof(QueueNode)); NewNode->next = NULL; NewNode->data = x; if (pq->head == NULL) { pq->head = NewNode; pq->tail = NewNode; } else { pq->tail->next = NewNode; pq->tail = NewNode; } pq->size++; } //出队列 void QueuePop(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); //剩余一个节点的情况 if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QueueNode* del = pq->head; pq->head = pq->head->next; free(del); } pq->size--; } //返回队列的首元素 QdataType QueueFront(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->head->data; } //返回队列的尾部元素 QdataType QueueBack(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->tail->data; } //队列的大小 int QueueSize(Queue* pq) { //assert(pq); //int n = 0; //QueueNode* cur = pq->head; //while (cur) //{ // n++; // cur = cur->next; //} //return n; return pq->size; } //判断队列是否为空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL && pq->tail == NULL; }
以上就是队列的实现的所有内容了,希望可以帮到你!