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语言链式队列与循环队列怎么实现”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道。
推荐阅读
-
C/C++如何获取CAN信号
-
C语言怎么通过二分查找实现猜数字游戏
-
C语言数据结构中的线性表怎么使用
-
C语言的数据结构怎么理解
C语言的数据结构怎么理解这篇文章主要介绍了C语言的数据结构怎么理解...
-
C语言与C++中内存管理的方法
-
C语言冒泡排序怎么实现
-
C语言如何实现斐波那契数列
C语言如何实现斐波那契数列这篇文章主要介绍了C语言如何实现斐波那契...
-
C语言如何实现无符号数和有符号数间的运算
-
C语言中常用的头文件是什么
C语言中常用的头文件是什么这篇文章主要介绍“C语言中常用的头文件是...
-
C语言如何利用DES模块实现加密功能
C语言如何利用DES模块实现加密功能这篇文章主要讲解了“C语言如何...