C语言队列怎么实现
今天小编给大家分享一下C语言队列怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
队列的实现
基本概念
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低需要挪动数据O(N)。而链表结构头删只需要O(1)。尾插定义一个尾指针,也只需要O(1)。
创建结构体
这是一个嵌套结构体。
实参q的地址传给了形参pq。pq就是一个指向结构体Queue的指针。Queue里面的head是指向队列对头的指针,tail是指向队尾的指针。
int main(){//创建结构体变量q//需要传q的地址过去。Queue q;return 0;}
定义一个尾指针tail方便入队的尾插。头指针head方便出队时的头删。
typedef int QDataType;//节点结构体typedef struct QueueNode{QDataType data;struct QueueNode* next;}QNode;//头指针和尾指针的结构体typedef struct Queue{QNode* head;QNode* tail;}Queue;
初始化结构体
才开始还没有创建队列的空间,所以只需要初始化第一个结构体就ok了。队列初始状态需要对头和队尾指向同一位置,且都是空。
void QueueInit(Queue* pq){assert(pq);pq->head = pq->tail = NULL;}
销毁队列结构体
这次我把销毁结构体放在初始化结构体的后面,原因是内存泄漏很严重,但是经常会忘记销毁结构体。创建意味着就要销毁,二者对立,所以排在初始化的后面,理所应当。
void QueueDestory(Queue* pq){assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;}
入队
入队的时候,会创建新的节点。最好最好把新开的newnode节点初始化。把他的next置为空,方便后期求队列长度函数,和出队函数的循环条件的书写。
void QueuePush(Queue* pq, QDataType x){assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));assert(newnode);//下面两个初始化很有必要newnode->data = x;newnode->next = NULL;if (pq->tail == NULL){assert(pq->head == NULL);pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}}
出队
因为Queue结构体不可能为空,所以需要断言
还需要断言pq->head和tail都不为空。
void QueuePop(Queue* pq){assert(pq);assert(pq->head && pq->tail);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;}}
判断队列是否为空
为空返回true,为假返回false
bool QueueEmpty(Queue* pq){assert(pq);return pq->head == NULL;}
访问对头的值
QDataType QueueFront(Queue* pq){assert(pq);assert(pq->head);return pq->head->data;}
访问队尾的值
QDataType QueueBack(Queue* pq){assert(pq);assert(pq->tail);return pq->tail->data;}
返回队列的长度
长度不可能为负数,所以返回类型为size_t
size_t QueueSize(Queue* pq){assert(pq);QNode* cur = pq->head;size_t size = 0;while (cur){size++;cur = cur->next;}return size;}
Queue.h
#pragma once#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <assert.h>typedef int QDataType;typedef struct QueueNode{QDataType data;struct QueueNode* next;}QNode;typedef struct Queue{QNode* head;QNode* tail;//size_t size;}Queue;void QueueInit(Queue* pq);void QueueDestory(Queue* pq);void QueuePush(Queue* pq, QDataType x);void QueuePop(Queue* pq);bool QueueEmpty(Queue* pq);size_t QueueSize(Queue* pq);QDataType QueueFront(Queue* pq);QDataType QueueBack(Queue* pq);
Queue.c
#include "Queue.h"void QueueInit(Queue* pq){assert(pq);pq->head = pq->tail = NULL;}void QueueDestory(Queue* pq){assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;}void QueuePush(Queue* pq, QDataType x){assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));assert(newnode);newnode->data = x;newnode->next = NULL;if (pq->tail == NULL){assert(pq->head == NULL);pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}}void QueuePop(Queue* pq){assert(pq);assert(pq->head && pq->tail);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;}}bool QueueEmpty(Queue* pq){assert(pq);return pq->head == NULL;}size_t QueueSize(Queue* pq){assert(pq);QNode* cur = pq->head;size_t size = 0;while (cur){size++;cur = cur->next;}return size;}QDataType QueueFront(Queue* pq){assert(pq);assert(pq->head);return pq->head->data;}QDataType QueueBack(Queue* pq){assert(pq);assert(pq->tail);return pq->tail->data;}
Test.c
void TestQueue(){Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);printf("%d ", QueueFront(&q));QueuePop(&q);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}printf("\n");}int main(){TestQueue();return 0;}
以上就是“C语言队列怎么实现”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341