C语言链式队列与循环队列怎么实现

C语言链式队列与循环队列怎么实现

这篇文章主要介绍了C语言链式队列与循环队列怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言链式队列与循环队列怎么实现文章都会有所收获,下面我们一起来看看吧。

队列的实现

队列是一种先进先出(First in First Out)的线性表,简称FIFO。与栈不同,栈是一种后进先出(先进后出)的线性表。在队列中,允许插入的一端称为队尾,允许删除的一端称为队头。假设队列是q=(a1,a2,…,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,列在最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然在队伍的最后。队列分为顺序队列和循环队列。顺序队列我们可以利用数组或者链表实现。这里,我们选择用链表实现顺序队列。

今天主要介绍链表实现的队列和循环队列

链式队列

队列主要有哪些基本操作

//初始化队列voidQueueInit(Queue*q);//队尾入队列voidQueuePush(Queue*q,QDataTypedata);//队头出队列voidQueuePop(Queue*q);//获取队列头部元素QDataTypeQueueFront(Queue*q);//获取队列队尾元素QDataTypeQueueBack(Queue*q);//获取队列中有效元素个数intQueueSize(Queue*q);//检测队列是否为空,如果为空返回非零结果,如果非空返回0boolQueueEmpty(Queue*q);//销毁队列voidQueueDestroy(Queue*q);

链式队列的定义

typedefintQDataType;//链式结构:表示队列typedefstructQListNode{structQListNode*_next;QDataType_data;}QNode;//队列的结构typedefstructQueue{QNode*_front;QNode*_rear;}Queue;

链式队列的实现

1、初始化队列

voidQueueInit(Queue*q){assert(q);q->_front=NULL;q->_rear=NULL;}

2、销毁队列

voidQueueDestroy(Queue*q){assert(q);QNode*cur=q->_front;while(cur!=NULL){QNode*next=cur->_next;free(cur);cur=next;}q->_front=q->_rear=NULL;}

3、队列判空

boolQueueEmpty(Queue*q){assert(q);//if(q->_front==NULL)//{//return1;//}//else//{//return0;//}returnq->_front==NULL;}

4、入队操作

voidQueuePush(Queue*q,QDataTypedata){assert(q);QNode*newnode=(QNode*)malloc(sizeof(QNode));if(newnode==NULL){exit(-1);}newnode->_data=data;newnode->_next=NULL;if(q->_front==NULL){q->_front=q->_rear=newnode;}else{q->_rear->_next=newnode;q->_rear=newnode;}}

5、出队操作

voidQueuePop(Queue*q){assert(q);assert(!QueueEmpty(q));QNode*next=q->_front->_next;free(q->_front);q->_front=next;if(q->_front==NULL){q->_rear=NULL;}}

6、取队头元素

QDataTypeQueueFront(Queue*q){assert(q);assert(!QueueEmpty(q));returnq->_front->_data;}

7、取队尾操作

QDataTypeQueueBack(Queue*q){assert(q);assert(!QueueEmpty(q));returnq->_rear->_data;}

8、队中有效元素个数

intQueueSize(Queue*q){assert(q);intsize=0;QNode*cur=q->_front;while(cur){size++;cur=cur->_next;}returnsize;}

循环队列

循环队列的定义

循环队列就是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。在循环队列结构中,当存储空间的最后一个位置已被使用而再要进入队运算时,只需要存储空间的第一个位置空闲,便可将元素加入到第一个位置,即将存储空间的第一个位置作为队尾。循环队列可以更简单防止伪溢出的发生,但队列大小是固定的。在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是front=rear,而队列判满的条件是front=(rear+1)%MaxSize。

循环队列的空间可以重复利用,解决了普通队列的空间浪费问题

循环队列的实现

typedefstruct{int*a;intfront;inttail;intk;}MyCircularQueue;//提前声明判空判满boolmyCircularQueueIsEmpty(MyCircularQueue*obj);boolmyCircularQueueIsFull(MyCircularQueue*obj);//创建循环队列MyCircularQueue*myCircularQueueCreate(intk){MyCircularQueue*cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));cq->a=(int*)malloc(sizeof(int)*(k+1));cq->front=cq->tail=0;cq->k=k;returncq;}//循环队列入队boolmyCircularQueueEnQueue(MyCircularQueue*obj,intvalue){if(myCircularQueueIsFull(obj)){returnfalse;}obj->a[obj->tail]=value;obj->tail++;obj->tail%=(obj->k+1);returntrue;}//循环队列出队boolmyCircularQueueDeQueue(MyCircularQueue*obj){if(myCircularQueueIsEmpty(obj)){returnfalse;}obj->front++;obj->front%=(obj->k+1);returntrue;}//循环队列取队头intmyCircularQueueFront(MyCircularQueue*obj){if(myCircularQueueIsEmpty(obj)){return-1;}returnobj->a[obj->front];}//循环队列取队尾intmyCircularQueueRear(MyCircularQueue*obj){if(myCircularQueueIsEmpty(obj)){return-1;}inti=(obj->tail+obj->k)%(obj->k+1);returnobj->a[i];}//循环队列判空boolmyCircularQueueIsEmpty(MyCircularQueue*obj){returnobj->front==obj->tail;}//循环队列判满boolmyCircularQueueIsFull(MyCircularQueue*obj){return(obj->tail+1)%(obj->k+1)==obj->front;}//销毁循环队列voidmyCircularQueueFree(MyCircularQueue*obj){free(obj->a);free(obj);}

关于“C语言链式队列与循环队列怎么实现”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C语言链式队列与循环队列怎么实现”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道。

发布于 2022-04-15 22:27:30
收藏
分享
海报
0 条评论
35
上一篇:.Net Core怎么解决WebAPI中返回时间格式带T的问题 下一篇:Java并发编程之StampedLock锁怎么应用
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码