队列的两种存储方式的介绍与实现
2017-07-31 14:38
239 查看
简介
队列是一种特殊的线性表,它的特殊之处在于它必须在队列的头部进行删除元素,在队列尾部插入元素。我们把队列的头部称为对头(front),队列尾部叫做队尾(rear)。进行删除元素位置叫队头(front),进行插入元素的位置叫在队尾(rear)。队列的存储的数据称为队列元素,因为只能在对头进行删除的操作,队尾进行插入,先插入的先出队,所以我们可以称队列为一种先进先出(FIFO:first in first out )的数据结构。
顺序队列
创建顺序存储结构,我们必须动态申请或静态地分配一块存储位置,设置两个指针来进行管理,分别称为对头head、队尾tail,当队头与队尾相等时(head==tail)我们称为队空。队头指针指向队列第一个插入的元素,tail指针指向队列最后一个插入元素的下一个位置,当队列中插入一个元素时,tail+1;删除
一个元素时,head+1。
我们来看一个图:
在图中我们可以到,图1.3,当队头元素被删除后,会留下一块存储区域,它并不会再次被使用,所以会造成内存的浪费。图1.4中反应了这样一个现象,当队列所
申请的内存最后一块存储空间被占有时,当想要再插入一个新的元素时,就会产生问题,这种现象称为“假溢出”。
为了避免上述的问题,因此出现了一个新的概念:循环队列。
循环队列
循环队列,我们假想成一个循环模型,如下图所示:当front==rear时表示队空;当循环出队列、入队列的过程中会发生一种情况,队尾在元素一的位置,队头在元素二的位置,那么头尾指针也恰好指向同一个位置,这时我们称为队满,是不是也是front==rear?
这里我用数组方式来实现循环队列:
typedef int QueType; typedef int Status; #define capacity 4
*采用数据存储元素,数组类型为:int *实现队列初始化、出队列、入队列、统计队列总数、循环遍历队列元素等功能。 */ typedef struct{ int head;//头 int tail;//尾 QueType queArr[capacity];//队列数组 }myQueue; //队列初始化 int InitQueue(myQueue *q){ //q = (myQueue *)malloc(sizeof(myQueue)); q->head = q->tail = 0 ;//头和尾相等,此时为空 return 0; } //判断队列是否为空 //为空返回0,否则为-1 int QueueEmpity(myQueue *q){ if(q->head == q->tail){//首尾相等,队列为空 return 0; } return -1 ; } //判断队列是否已满 //为空返回0,否则为-1 int QueueFull(myQueue *q){ //避免和队列为空时冲突。队列中实际还差一个位置。 if(q->head == (q->tail+1)%(capacity)){//为满时, return 0; } return -1 ; } //入队 Status EnQueueEle(myQueue *q , QueType ele){ if(QueueFull(q) == -1){//不为满 q->queArr[q->head] = ele; //重置队尾 q->tail = (q->tail+1) % (capacity); }else{ printf("队列已满\n"); return -1; } return 0; } //出队 int DeQueueEle( myQueue *q,QueType *ele){ if(QueueEmpity(q) == -1){//不为空 *ele = q->queArr[q->head]; q->head ++; //重置队首 q->head = (q->head+1) % (capacity); }else{ printf("队列为空\n"); return -1; } return 0; } //获取第一元素 int GetHead(myQueue *q ,QueType *ele){ *ele = q->queArr[q->head]; return 0; } //统计队列元素个数 int getQueueSize(myQueue *q){ return (capacity - q->head + q->tail)%(capacity) ; } //遍历元素 void showQueueList(myQueue *q){ int i,size ; size = getQueueSize(q); for(i = q->head ; i < size ;i++){ printf("队列中的元素:%d\n",q->queArr[i]); } }测试:
int main(void){ int ret = 0; int size = 0; myQueue *que ; que = (myQueue *)malloc(sizeof(myQueue)); //que->head = que->tail=0; InitQueue(que); EnQueueEle(que , 1); printf("增加一个元素\n"); size = getQueueSize(que); printf("队列元素个数为[%d]\n",size); showQueueList(que); free(que); return 0; }
结果:
相关文章推荐
- 队列的两种存储方式的介绍与实现(后续)
- Java可阻塞队列的两种实现方式 (传统wait/notify和jdk1.5以后的lock)
- rabbitmq 实现延迟队列的两种方式
- Java实现阻塞队列的两种方式
- 队列的链式存储方式的实现(Java语言描述)
- 队列的链式存储方式的实现(Java语言描述)
- 队列的链式存储的两种定义方式
- 队列的C++实现(两种方式)
- 安装php扩展pthreads实现PHP多线程 原创qw871122015-04-16 17:01评论(0)948人阅读 下面介绍两种编译方式: 1、在已有的PHP上编译pthreads扩展 注:需
- 队列的两种实现方式
- LinkedList实现堆栈数据结构的存储方式与队列的数据结构存储方式
- 简单介绍AOP两种实现方式
- 大话数据结构(六)——队列的两种java实现方式
- Java可阻塞队列的两种实现方式
- 实现动态代理的两种方式介绍+例子demo(JDK、CGlib)
- 用JAVA实现汉字转拼音缩写(两种方式介绍)
- 【Flask】Flask实现密码存储安全性的两种方式
- 数据结构队列的java实现,包括线性和链式两种方式
- [置顶] rabbitmq 实现延迟队列的两种方式