赞
踩
一、定义
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特性。
队尾:进行插入操作的一端。
队头:进行删除操作的一端。
二、结构体定义
- // 链式结构:表示队列
- typedef int QDataType;
- typedef struct QListNode
- {
- struct QListNode* next;
- QDataType data;
- }QNode;
-
- // 队列的结构
- typedef struct Queue
- {
- QNode* front;//队头
- QNode* rear;//队尾
- }Queue;
若采用顺序表的方式实现队列,随着出队入队的操作,队头指针和队尾指针的移动,队头前的空间就可能发生内存泄漏,或出现假溢出问题。对此有两种解决方法,一种是采用链表的方式实现队列,一种是采用循环队列,这里采用的是链表的方式实现队列,随后会发布循环队列的实现方法。
三、接口实现
- void Queue_Tese();//队列功能测试函数
- QNode* buyQNode(QDataType data);//带头结点的单链表
- void QueueInit(Queue* q);// 初始化队列
- void QueuePush(Queue* q, QDataType data);// 队尾入队列
- void QueuePop(Queue* q);// 队头出队列
- QDataType QueueFront(Queue* q);// 获取队列头部元素
- QDataType QueueBack(Queue* q);// 获取队列队尾元素
- int QueueSize(Queue* q);// 获取队列中有效元素个数
- int QueueEmpty(Queue* q);// 检测队列是否为空,为空返回1,非空返回0
- void QueueDestroy(Queue* q);// 销毁队列
1.创建带头结点的单链表
- QNode* buyQNode(QDataType data) {//带头结点的单链表
- QNode* newNode = (QNode*)malloc(sizeof(QNode));
- if (newNode == NULL) {
- assert(0);
- return NULL;
- }
- newNode->data = data;
- newNode->next = NULL;
- return newNode;
- }
使用带头结点的单链表实现队列,可以简化实现过程的很多操作。
2.初始化队列
- void QueueInit(Queue* q) {// 初始化队列
- assert(q);
- q->front = buyQNode(0);
- q->rear = q->front;
- }
将队列头尾指针都指向头结点即可。
3.入队
- void QueuePush(Queue* q, QDataType data) {// 队尾入队列
- assert(q);
- QNode* newNode = buyQNode(data);
- q->rear->next = newNode;
- q->rear = newNode;
- }
只能在队尾入队。
4.判空
- int QueueEmpty(Queue* q) {// 检测队列是否为空,为空返回1,非空返回0
- assert(q);
- return q->front == q->rear;
- }
队头队尾指针都在初始位置指向头结点,即队列为空,若用顺序表实现则是队头队尾都在0号位置即队列为空。
5.出队
- void QueuePop(Queue* q){// 队头出队列
- assert(q);
- if (QueueEmpty(q)) {//判空
- return;
- }
- QNode* delNode = q->front->next;
- q->front->next = delNode->next;
- if (delNode == q->rear) {//若队列只有一个元素,出队列后要将队尾放到头结点处
- q->rear = q->front;
- }
- free(delNode);
- }
出队列只能在队头出队。因为这里采用的是带头结点的单链表实现队列,所以在队列只有一个元素时出队列,需要把队尾指针放回到头节处。
6.获取队头
- QDataType QueueFront(Queue* q) {// 获取队列头部元素
- assert(q);
- return q->front->next->data;
- }
7.获取队尾
- QDataType QueueBack(Queue* q) {// 获取队列队尾元素
- assert(q);
- return q->rear->data;
- }
8.获取队列中有效元素个数
- int QueueSize(Queue* q) {// 获取队列中有效元素个数
- assert(q);
- QNode* cur = q->front->next;
- int len = 0;
- while (cur) {
- len++;
- cur = cur->next;
- }
- return len;
- }
通过单链表的遍历计数实现。
9.队列销毁
- void QueueDestroy(Queue* q) {// 销毁队列
- assert(q);
- QNode* cur = q->front->next;
- while (cur) {
- q->front->next = cur->next;
- free(cur);
- cur = q->front->next;
- }
- free(q->front);
- q->front = q->rear = NULL;
- }
循环释放每个结点,最后置空头尾指针。
四、接口测试
1.测试用例
- void Queue_Tese() {//队列功能测试函数
- Queue q;
- QueueInit(&q);
- printf("size = %d\n", QueueSize(&q));
-
- // 入队列
- QueuePush(&q, 1);
- QueuePush(&q, 2);
- QueuePush(&q, 3);
- QueuePush(&q, 4);
- QueuePush(&q, 5);
- QueuePush(&q, 6);
- QueuePush(&q, 7);
- printf("\nsize = %d\n", QueueSize(&q));
- printf("front = %d\n", QueueFront(&q));
- printf("back = %d\n", QueueBack(&q));
-
- // 出队列
- QueuePop(&q);
- printf("\nsize = %d\n", QueueSize(&q));
- printf("front = %d\n", QueueFront(&q));
- printf("back = %d\n", QueueBack(&q));
-
- QueuePop(&q);
- QueuePop(&q);
- QueuePop(&q);
- QueuePop(&q);
- QueuePop(&q);
- printf("\nsize = %d\n", QueueSize(&q));
- printf("front = %d\n", QueueFront(&q));
- printf("back = %d\n", QueueBack(&q));
-
- QueuePop(&q);
- QueuePop(&q);
- printf("\nsize = %d\n", QueueSize(&q));
- QueueDestroy(&q);
- }
2.测试结果
五、完整代码
- #include<stdio.h>
- #include<assert.h>
- #include<malloc.h>
-
- // 链式结构:表示队列
- typedef int QDataType;
- typedef struct QListNode
- {
- struct QListNode* next;
- QDataType data;
- }QNode;
-
- // 队列的结构
- typedef struct Queue
- {
- QNode* front;//队头
- QNode* rear;//队尾
- }Queue;
- void Queue_Tese();//队列功能测试函数
- QNode* buyQNode(QDataType data);//带头结点的单链表
- void QueueInit(Queue* q);// 初始化队列
- void QueuePush(Queue* q, QDataType data);// 队尾入队列
- void QueuePop(Queue* q);// 队头出队列
- QDataType QueueFront(Queue* q);// 获取队列头部元素
- QDataType QueueBack(Queue* q);// 获取队列队尾元素
- int QueueSize(Queue* q);// 获取队列中有效元素个数
- int QueueEmpty(Queue* q);// 检测队列是否为空,为空返回1,非空返回0
- void QueueDestroy(Queue* q);// 销毁队列
-
- int main() {
- Queue_Tese();
- return 0;
- }
-
- QNode* buyQNode(QDataType data) {//带头结点的单链表
- QNode* newNode = (QNode*)malloc(sizeof(QNode));
- if (newNode == NULL) {
- assert(0);
- return NULL;
- }
- newNode->data = data;
- newNode->next = NULL;
- return newNode;
- }
-
- void QueueInit(Queue* q) {// 初始化队列
- assert(q);
- q->front = buyQNode(0);
- q->rear = q->front;
- }
-
- void QueuePush(Queue* q, QDataType data) {// 队尾入队列
- assert(q);
- QNode* newNode = buyQNode(data);
- q->rear->next = newNode;
- q->rear = newNode;
- }
-
- int QueueEmpty(Queue* q) {// 检测队列是否为空,为空返回1,非空返回0
- assert(q);
- return q->front == q->rear;
- }
-
- void QueuePop(Queue* q){// 队头出队列
- assert(q);
- if (QueueEmpty(q)) {//判空
- return;
- }
- QNode* delNode = q->front->next;
- q->front->next = delNode->next;
- if (delNode == q->rear) {//若队列只有一个元素,出队列后要将队尾放到头结点处
- q->rear = q->front;
- }
- free(delNode);
- }
-
- QDataType QueueFront(Queue* q) {// 获取队列头部元素
- assert(q);
- return q->front->next->data;
- }
-
- QDataType QueueBack(Queue* q) {// 获取队列队尾元素
- assert(q);
- return q->rear->data;
- }
-
- int QueueSize(Queue* q) {// 获取队列中有效元素个数
- assert(q);
- QNode* cur = q->front->next;
- int len = 0;
- while (cur) {
- len++;
- cur = cur->next;
- }
- return len;
- }
-
- void QueueDestroy(Queue* q) {// 销毁队列
- assert(q);
- QNode* cur = q->front->next;
- while (cur) {
- q->front->next = cur->next;
- free(cur);
- cur = q->front->next;
- }
- free(q->front);
- q->front = q->rear = NULL;
- }
-
- void Queue_Tese() {//队列功能测试函数
- Queue q;
- QueueInit(&q);
- printf("size = %d\n", QueueSize(&q));
-
- // 入队列
- QueuePush(&q, 1);
- QueuePush(&q, 2);
- QueuePush(&q, 3);
- QueuePush(&q, 4);
- QueuePush(&q, 5);
- QueuePush(&q, 6);
- QueuePush(&q, 7);
- printf("\nsize = %d\n", QueueSize(&q));
- printf("front = %d\n", QueueFront(&q));
- printf("back = %d\n", QueueBack(&q));
-
- // 出队列
- QueuePop(&q);
- printf("\nsize = %d\n", QueueSize(&q));
- printf("front = %d\n", QueueFront(&q));
- printf("back = %d\n", QueueBack(&q));
-
- QueuePop(&q);
- QueuePop(&q);
- QueuePop(&q);
- QueuePop(&q);
- QueuePop(&q);
- printf("\nsize = %d\n", QueueSize(&q));
- printf("front = %d\n", QueueFront(&q));
- printf("back = %d\n", QueueBack(&q));
-
- QueuePop(&q);
- QueuePop(&q);
- printf("\nsize = %d\n", QueueSize(&q));
- QueueDestroy(&q);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。