每日消息!UC头条:队列实现图书信息管理(C语言)

2023-06-01 09:29:12| 来源: 个人图书馆-cnzrp|

用队列实现一个图书信息管理,这里放一下有哪些文件。(ps:我之前写的是学生信息管理,但是有人说我们的作业是写图书,就该了下内容,没有改文件名)

队列是用链表实现的,因为涉及到队列的一些特性,选择链表比数组会更优。


(资料图片仅供参考)

点击加载图片

Queue.h

#pragmaonce防止库函数的重复引用,因为库函数会在预编译的时候在程序中展开,会增大程序的体积。

通过typedef对数据重命名,之后需要修改数据就十分方便。并且其他函数不需要太多的改动。

这里结构体传的是指针,减少没必要的内存消耗。

队列的特性是先进先出所以和栈一样只有进出队列,不存在头插尾插、头删尾删的问题。

这里的图书价格应该使用浮点数类型更合适,只是我之前写的是学生信息管理,不想改了,就这样吧,意思get就行。

#pragmaonce#include#include#includetypedefstruct{charname[20];charauthor[20];intbno;intprice;}QDataType;typedefstructQListNode{structQListNode*next;QDataTypedata;}QNode;//队列的结构typedefstructQueue{QNode*head;QNode*tail;intsize;}Queue;//初始化队列voidQueueInit(Queue*q);//打印voidQueuePrint(Queue*q);//队尾入队列voidQueuePush(Queue*q,QDataType*data);//队头出队列voidQueuePop(Queue*q);//获取队列头部元素QDataType*QueueFront(Queue*q);//获取队列队尾元素QDataType*QueueBack(Queue*q);//获取队列中有效元素个数intQueueSize(Queue*q);//检测队列是否为空,如果为空返回非零结果,如果非空返回0intQueueEmpty(Queue*q);//销毁队列voidQueueDestroy(Queue*q);

main.c

因为重点在于数据结构队列的使用,所以直接给定一些数据,就不进行重复繁琐的数据输入工作了。

#define_CRT_SECURE_NO_WARNINGS1#include"Queue.h"voidtest{Queueq;QueueInit(&q);QDataTypebook1={"活着","余华",110701,22};QDataTypebook2={"人血馒头","余华",110702,21};QDataTypebook3={"人间词话","王国维",110703,23};QDataTypebook4={"小词大雅","叶嘉莹",110704,22};QDataTypebook5={"且听风吟","村上春树",110705,23};QueuePush(&q,&book1);QueuePush(&q,&book2);QueuePush(&q,&book3);QueuePush(&q,&book4);QueuePush(&q,&book5);QueuePrint(&q);printf("%d\n\n",QueueSize(&q));QDataType*head=QueueFront(&q);printf("%s%d%s%d\n\n",head->name,head->bno,head->author,head->price);QDataType*tail=QueueBack(&q);printf("%s%d%s%d\n\n",tail->name,tail->bno,tail->author,tail->price);QueuePop(&q);QueuePop(&q);QueuePop(&q);QueuePrint(&q);printf("%d\n",QueueSize(&q));QueueDestroy(&q);}intmain{test;return0;}

Queue.c

打印函数的实现,如果队列中的数据类型发生了改变,其他功能函数基本上不需要有什么变化,打印函数对应修改一下就行了,因为打印需要涉及到具体的数据问题。

voidQueuePrint(Queue*q){QNode*next=q->head;while(next!=NULL){printf("%s%d%s%d\n",next->data.name,next->data.bno,next->data.author,next->data.price);next=next->next;}printf("\n");}

队列的初始化,将头尾指针都置为NULL,size置为0。

//队列初始化voidQueueInit(Queue*q){q->head=NULL;q->tail=NULL;q->size=0;}

入队列的实现,先要创建一个节点来存放数据,然后把这个队列插入到队尾。如果这个队列的队尾指针为空,就说明这个队列中并没有数据,那么这个新插入的数据就既是队首又是队尾。如果队列的队尾指针有值,就把新节点插入到当前队尾之后,然后再把队尾指针向后移动一位。插入数据之后要将size加一。

voidQueuePush(Queue*q,QDataType*x){assert(q);QNode*newnode=(QNode*)malloc(sizeof(QNode));if(newnode==NULL){perror("mallocfail");exit(-1);}newnode->data=*x;newnode->next=NULL;if(q->tail==NULL){q->head=q->tail=newnode;}else{q->tail->next=newnode;q->tail=newnode;}q->size++;}

出队列的实现。因为节点是动态开辟的空间,所以出队列之后,要将这个节点的空间释放掉。队列的特性是先入先出,所以,出队列就是删除头结点。删除头结点之前要保存第二个节点的位置,然后删除掉头结点,把第二个节点作为头结点返回。删除数据之后,要将size减一。

voidQueuePop(Queue*q){assert(q);assert(!QueueEmpty(q));if(q->head->next==NULL){free(q->head);q->head=q->tail=NULL;q->size--;}else{QNode*del=q->head;q->head=q->head->next;q->size--;free(del);}}

获取队列头部元素,这里返回的是一个结构体指针,还是为了减少空间的使用,因为队列本身就具备头指针,所以获取队列头部元素就十分简单。

QDataType*QueueFront(Queue*q){assert(q);assert(!QueueEmpty(q));return&(q->head->data);}

获取队列队尾元素,一样返回的是一个结构体指针,实现和获取头部元素基本一样。

QDataType*QueueBack(Queue*q){assert(q);assert(!QueueEmpty(q));return&(q->tail->data);}

获取队列元素个数,不要太简单,本身就有个size,直接返回size就行。

intQueueSize(Queue*q){assert(q);returnq->size;}

检测队列是否为空,如果为空返回非零结果,如果非空返回0。当首尾指针都为空时,队列中就必然没有数据。

intQueueEmpty(Queue*q){assert(q);returnq->head==NULL&&q->tail==NULL;}

队列的销毁,因为空间是动态开辟的,所以需要释放空间,如果不释放空间会造成内存泄露。逐一将队列中的节点空间释放掉,最后head和tail的next指针都为NULL,也不需要我们手动置为NULL了。

voidQueueDestroy(Queue*q){assert(q);while(q->head){QNode*next=q->head;q->head=q->head->next;free(next);}}

关键词

  1. 最近更新

Powered by www.firstproduction.net  第一产经网

备案号:豫ICP备2022016495号-9© 2013-2017   联系我们:939 674 669@qq.com