目次
一、弁言
二、团体思绪
三、代码模块分析
(一)头文件包罗与宏界说
(二)数据范例界说
(三)队列利用函数
1. 队列初始化
2. 队列烧毁
3. 入队利用
4. 出队利用
5. 获取队头元素
6. 获取队尾元素
7. 获取队列巨细
8. 判定队列是否为空
(四)主函数测试
四、总结
作者主页:共享家9527-CSDN博客
一、弁言
队列是一种紧张的数据布局,依照先辈先出(FIFO)的原则。在C语言中,我们可以通过自界说布局体和一系列利用函数来实现一个队列。本文将详细先容怎样实现一个简单的队列,并对代码的各个部门举行深入分析。
二、团体思绪
队列的实现紧张涉及队列节点的界说、队列布局体的界说以及对队列的各种利用,如初始化、入队、出队、获取队头和队尾元素、判定队列是否为空和获取队列巨细等。我们将这些利用模块化,每个函数负责一个特定的功能,使得代码布局清楚,易于维护和扩展。
三、代码模块分析
(一)头文件包罗与宏界说
- c
-
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<stdlib.h>
- #include<stdbool.h>
- #include<assert.h>
-
复制代码
_CRT_SECURE_NO_WARNINGS 宏界说用于关闭Visual Studio中一些函数的安全告诫。反面依次包罗了标准输入输出库、标准库、布尔范例库和断言库,为后续代码提供须要的功能支持。
(二)数据范例界说
- c
-
- typedef int QDatatype;
- typedef struct QueueNode
- {
- struct QueueNode* next;
- QDatatype data;
- }QNode;
- typedef struct Queue
- {
- QNode* head;
- QNode* tail;
- int size;
- }Queue;
-
复制代码
- QDatatype 界说为 int 范例,表现队列中存储的数据范例,这里是整型,也可以根据现实需求改为其他范例。
- QueueNode 布局体界说了队列节点,包罗一个指向下一个节点的指针 next 和存储数据的 data 成员。
- Queue 布局体表现整个队列,包罗指向队头的指针 head 、指向队尾的指针 tail 和记载队列元素个数的 size 。
(三)队列利用函数
1. 队列初始化
- c
-
- void QueueInit(Queue* pq)
- {
- pq->head = pq->tail = NULL;
- pq->size = 0;
- }
-
复制代码
QueueInit 函数用于初始化一个队列,将队头和队尾指针设为 NULL ,队列巨细设为 0 。
2. 队列烧毁
- c
-
- void QueueDestroy(Queue* pq)
- {
- assert(pq);
- Queue* cur = pq->head;
- while (cur)
- {
- pq->head = pq->head->next;
- free(cur);
- cur = pq->head;
- }
- pq->head = pq->tail = NULL;
- pq->size = 0;
- }
-
复制代码
QueueDestroy 函数用于开释队列占用的内存空间。通过遍历队列,逐个开释每个节点,末了将队头、队尾指针设为 NULL ,队列巨细设为 0 。
3. 入队利用
- c
-
- void QueuePush(Queue* pq, QDatatype x)
- {
- QNode* newnode = (QNode*)malloc(sizeof(QNode));
- if (newnode == NULL)
- {
- perror("malloc fail");
- return;
- }
- newnode->data = x;
- newnode->next = NULL;
- if (pq->head == NULL)
- {
- pq->head = pq->tail = newnode;
- }
- else
- {
- pq->tail->next = newnode;
- pq->tail = newnode;
- }
- pq->size++;
- }
-
复制代码
QueuePush 函数用于将一个元素入队。起首分配一个新节点的内存空间,若分配失败则打印错误信息并返回。然后将新节点的数据设为传入的元素值, next 指针设为 NULL 。如果队列为空,则新节点既是队头也是队尾;否则将新节点毗连到队尾,并更新队尾指针。末了队列巨细加 1 。
4. 出队利用
- c
-
- void QueuePop(Queue* pq)
- {
- assert(pq);
- assert(pq->head != NULL);
- if (pq->head->next == NULL)
- {
- free(pq->head);
- pq->head = pq->tail = NULL;
- }
- else
- {
- QNode* next = pq->head->next;
- free(pq->head);
- pq->head = next;
- }
- pq->size--;
- }
-
复制代码
QueuePop 函数用于将队头元素出队。起首举行断言,确保队列指针有用且队列不为空。如果队列只有一个元素,开释队头节点并将队头、队尾指针设为 NULL ;否则生存队头节点的下一个节点,开释队头节点,然后将队头指针指向下一个节点。末了队列巨细减 1 。
5. 获取队头元素
- c
-
- QDatatype QueueFront(Queue* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
- return pq->head->data;
- }
复制代码
QueueFront 函数用于获取队头元素的值。先举行断言确保队列有用且不为空,然后返回队头节点的数据。
6. 获取队尾元素
- c
-
- QDatatype QueueBack(Queue* pq)
- {
- assert(pq);
- assert(!QueueEmpty(pq));
- return pq->tail->data;
- }
-
复制代码
QueueBack 函数用于获取队尾元素的值。同样先举行断言确保队列有用且不为空,然后返回队尾节点的数据。
7. 获取队列巨细
- c
-
- int QueueSize(Queue* pq)
- {
- return pq->size;
- }
-
-
- QueueSize 函数直接返回队列结构体中记录的元素个数。
-
复制代码
8. 判定队列是否为空
- c
-
- bool QueueEmpty(Queue* pq)
- {
- assert(pq);
- return pq->head == NULL;
- }
-
复制代码
QueueEmpty 函数通过判定队头指针是否为 NULL 来确定队列是否为空,为空则返回 true ,否则返回 false 。
(四)主函数测试
- c
-
- int main()
- {
- Queue Q;
- QueueInit(&Q);
- QueuePush(&Q, 1);
- QueuePush(&Q, 2);
- QueuePush(&Q, 3);
- QueuePush(&Q, 4);
- QueuePush(&Q, 5);
- while (!QueueEmpty(&Q))
- {
- printf("%d ", QueueFront(&Q));
- QueuePop(&Q);
- }
- printf("\n");
- QueueDestroy(&Q);
- return 0;
- }
-
复制代码
在 main 函数中,我们对实现的队列举行了测试。起首初始化一个队列,然后依次将 1 到 5 这五个元素入队,接着通过循环不停获取队头元素并打印,同时将其出队,直到队列为空。末了烧毁队列,开释内存。
四、总结
通过以上模块化的代码实现,我们完成了一个根本的队列数据布局。每个函数都有明确的功能,使得代码逻辑清楚,易于明确和维护。在现实应用中,可以根据详细需求对队列举行进一步的扩展和优化,如添加更多的利用函数大概改变数据存储范例等。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |