队列的顺序存储和链式存储
2017-08-10 19:01
411 查看
队列的基本概念
1.定义:队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。2.队列是一种先进先出的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。front指针指向对头元素,rear指针指向队尾的下一个位置。当front==rear时,为空队列。
队列的顺序存储(循环队列)
如图所示为队列的顺序存储:假设这个队列的总个数不超过5个,但目前如接着入队的话,因数组末尾元素已经占用,再向后加,就会出现数组越界的错误,可实际上,队列在下标0和1的地方还是空闲的。把这种现象称为“假溢出”。
这也是队列的顺序存储不足的地方。所以解决假溢出的办法就是后面满了,就再从头开始,也就是头尾相接的循环。
我们把队列的这种头尾相接的顺序存储结构称为循环队列。
判断队列满的条件:
*办法一是设置一个标志变量flag,当front==rear,且flag=0是为队列空,当front=rear,且flag=1时为队列满。
*办法二是当队列空时,条件就是front=rear,当队列满时,保留一个元素空间,数组中还有一个空闲单元。如图所示:
这里主要讨论第二种方法:由于rear可能比front大,也可能比front小,所以尽管它们只相差一个位置时就是满的情况,但也可能是相差整整一圈。所以若队列的最大尺寸为QueueSize,那么队列满的条件是:
(rear+1)%QueueSize == front
而队列的长度计算公式为:
(rear-front+QueueSize)%QueueSize
循环队列的代码实现:
"sqqueue.h" #pragma once typedef int ELEM_TYPE; #define MAXSIZE 10 typedef struct { ELEM_TYPE data[MAXSIZE]; int front; //头指针 int rear; //尾指针,若队列不为空,指向队列尾元素的下一个位置 }SqQueue; void InitQueue(SqQueue *q); void EnQueue(SqQueue *q,ELEM_TYPE e); void DeQueue(SqQueue *q,ELEM_TYPE *e); bool QueueEmpty(SqQueue q); int QueueLength(SqQueue q); void ClearQueue(SqQueue *q); void DestroyQueue(SqQueue *q); void QueueHead(SqQueue q,ELEM_TYPE *e); void ShowQueue(SqQueue q); "sqqueue.cpp" #include "sqqueue.h" #include <stdio.h> #include <stdlib.h> #include <assert.h> void InitQueue(SqQueue *q) { q->front = NULL; q->rear = NULL; int i; for (i=0;i<MAXSIZE;++i) { q->data[i] = 0; } } void EnQueue(SqQueue *q,ELEM_TYPE e) { if ((q->rear+1)%MAXSIZE == q->front) { printf("队列满\n"); return; } q->data[q->rear] = e; q->rear = (q->rear+1)%MAXSIZE;//rear指针向后移动一个位置,若到最后则返回数组头部 } void DeQueue(SqQueue *q,ELEM_TYPE *e) { if(q->front == q->rear) { printf("队列为空\n"); return; } *e = q->data[q->front]; q->front = (q->front+1)%MAXSIZE;//头指针向后移一个位置,若到最后则返回到数组头部 } bool QueueEmpty(SqQueue q) { return q.front == q.rear; } int QueueLength(SqQueue q) { return (q.rear-q.front+MAXSIZE)%MAXSIZE; } void ClearQueue(SqQueue *q) { assert(q != NULL); while (q->front != q->rear) { q->front = (q->front+1)%MAXSIZE; } } void DestroyQueue(SqQueue *q) { q->front = NULL; q->rear = NULL; } void QueueHead(SqQueue q,ELEM_TYPE *e) { if (q.front == q.rear) { printf("队列为空z\n"); return; } *e = q.data[q.front]; } void ShowQueue(SqQueue q) { while (q.front != q.rear) { printf("data:%d\n",q.data[q.front]); q.front = (q.front+1)%MAXSIZE; } }
队列的链式存储
代码实现:"linkqueue.h" #pragma once typedef int ELEM_TYPE; typedef struct QNode { ELEM_TYPE data; struct QNode *next; }QNode,*QueuePtr; typedef struct { QueuePtr front;//队头指针 QueuePtr rear;//队尾指针 }LinkQueue; void InitQueue(LinkQueue *q); void DestroyQueue(LinkQueue *q); void ClearQueue(LinkQueue *q); bool QueueEmpty(LinkQueue q); int QueueLength(LinkQueue q); void GetHead(LinkQueue q,ELEM_TYPE *e); void EnQueue(LinkQueue *q,ELEM_TYPE e); void DeQueue(LinkQueue *q,ELEM_TYPE *e); void showQueue(LinkQueue q); "linkqueue.cpp" #include "linkqueue.h" #include <stdio.h> #include <stdlib.h> #include <assert.h> void InitQueue(LinkQueue *q) { q->front = q->rear = (QueuePtr)malloc(sizeof(QNode)); if (!q->front) { exit(EXIT_FAILURE); } q->front->next = NULL; } void DestroyQueue(LinkQueue *q) { while (q->front) { q->rear = q->front->next; free(q->front); q->front = q->rear; } } void ClearQueue(LinkQueue *q) { QueuePtr p = q->front->next; while (p) { q->front->next = p->next; if (q->rear == p) { q->rear = q->front; } free(p); p = q->front->next; } } bool QueueEmpty(LinkQueue q) { if (q.front == q.rear) { return true; } else { return false; } } int QueueLength(LinkQueue q) { int i = 0; QueuePtr p = q.front->next; while(p) { i++; p = p->next; } return i; } void GetHead(LinkQueue q,ELEM_TYPE *e) { QueuePtr p = q.front->next; if (p) { *e = p->data; } } void EnQueue(LinkQueue *q,ELEM_TYPE e) { QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); if (!p) { exit(EXIT_FAILURE); } p->data = e; p->next = NULL; q->rear->next = p; q->rear = p; } void DeQueue(LinkQueue *q,ELEM_TYPE *e) { if (q->front == q->rear) { printf("队列为空\n"); return; } QueuePtr p = q->front->next; *e = p->data; q->front->next = p->next; if (q->rear == p) { q->rear = q->front; } free(p); } void showQueue(LinkQueue q) { assert(q.front != NULL); QueuePtr p = q.front->next; while (p) { printf("data:%d\n",p->data); p = p->next; } }
相关文章推荐
- 队列的顺序存储实现和链式存储实现
- 队列的链式存储与顺序存储
- 栈和队列的顺序存储和链式存储
- 队列的顺序存储和链式存储实现
- 队列的顺序和链式存储
- 数据结构-队列-顺序链式存储
- 队列——顺序存储与链式存储
- 数据结构—队列的顺序和链式存储
- 队列的顺序存储和链式表示方法-数据结构学习笔记2.3
- 队列的顺序存储与链式存储
- 数据结构之线性表——队列的顺序存储
- 队列的顺序存储
- 关于顺序存储和链式存储读写性能的比较(理论)
- 004 队列的顺序存储
- 二叉树的表示链式表示和顺序存储3.0
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
- 队列的链式存储结构
- 队列的链式存储
- 队列---顺序队列存储结构的不足(假溢出)
- 数据结构——队列之链式存储