标签:
(1) 定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
(2) 抽象数据类型
ADT 队列(Queue)
Data
同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
InitQueue(*Q):初始化操作,建立一个空队列Q;
DestoryQueue(*Q):若队列Q存在,则销毁它;
ClearQueue(*Q):将队列Q清空;
QueueEmpty(Q):若队列Q为空,返回true,否则返回false;
GetHead(Q, *e):若队列Q存在且非空,用e返回队列Q的队头元素;
EnQueue(*Q, e):若队列Q存在,插入新元素e到队列Q中并成为队尾元素;
DeQueue(*Q, *e):删除队列Q中队头元素,并用e返回其值;
QueueLength(Q):返回队列Q的元素个数。
endADT
(1) 队列顺序存储的不足:假溢出
举个例子:现实当中,你上了公交车,发现前排有两个空座位,而后排所有的座位都已经坐满,你会怎么做?立马下车,并对自己说,后面没座了,我等下一辆?
没有这么笨的人,前面有座位,当然也可以坐的,除非坐满了,才会考虑下一辆。
(2) 循环队列的定义
解决假溢出的办法就是后面满了,就再从头开始,也就是头尾相连接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。
(3) 判断队满的条件
(rear + 1) % QueueSize = front;
(4) 计算队列长度公式
(rear - front + QueueSize) % QueueSize;
(5) 参考代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define OK 0 5 #define ERROR 1 6 7 typedef int Status; 8 typedef int QElemType; 9 10 #define MAXQSIZE 100 // 最大队列长度 11 12 typedef struct 13 { 14 QElemType *base; // 初始化的动态分配存储空间 15 int front; // 头指针,若队列不空,指向队列头元素 16 int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置 17 } SqQueue; 18 19 Status initQueue(SqQueue &Q) // 构造一个空队列 20 { 21 Q.base = (QElemType *) malloc (MAXQSIZE * sizeof (QElemType)); 22 if (!Q.base) return ERROR; // 存储分配失败 23 Q.front = Q.rear = 0; 24 return OK; 25 } 26 27 int queueLength(SqQueue Q) // 返回Q的元素个数,即队列的长度 28 { 29 return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE; 30 } 31 32 Status EnQueue(SqQueue &Q, QElemType e) // 插入元素e为Q的新队尾元素 33 { 34 if ((Q.rear + 1) % MAXQSIZE == Q.front) 35 return ERROR; // 队列满 36 Q.base[Q.rear] = e; 37 Q.rear = (Q.rear + 1) % MAXQSIZE; 38 return OK; 39 } 40 41 Status DeQueue(SqQueue &Q, QElemType &e) // 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR 42 { 43 if (Q.front == Q.rear) return ERROR; 44 e = Q.base[Q.front]; 45 Q.front = (Q.front + 1) % MAXQSIZE; 46 return OK; 47 } 48 49 bool queueEmpty(SqQueue Q) 50 { 51 return Q.front == Q.rear; 52 } 53 54 int main(int argc, char *argv[]) 55 { 56 int n; 57 while (scanf("%d", &n) != EOF) 58 { 59 SqQueue Q; 60 initQueue(Q); 61 for (int i = 1; i <= n; i++) 62 EnQueue(Q, i); 63 bool flag = true; 64 while (!queueEmpty(Q)) 65 { 66 int e; 67 DeQueue(Q, e); 68 if (flag) printf("%d ", e); 69 else EnQueue(Q, e); 70 flag = !flag; 71 } 72 printf("\n"); 73 } 74 return 0; 75 }
(1) 链式存储结构
队列的链式存储结构,其实不是线性表的单链表,只不过它只能尾进头出而已。我们把它简称为链队列。
链队列的结构为:
typedef int QElemType; typedef struct QNode // 结点结构 { QElemType data; struct QNode *next; } QNode, *QueuePtr; typedef struct // 队列的链表结构 { QueuePtr front, rear; } LinkQueue;
(2) 入队、出队操作
1 Status EnQueue(LinkQueue *Q, QElemType e) 2 { 3 QueuePtr s = (QueuePtr) malloc (sizeof(QNode)); 4 if (!s) return ERROR; 5 s->data = e; 6 s->next = NULL; 7 Q->rear->next = s; 8 Q->rear = s; 9 return OK; 10 } 11 12 Status DeQueue(LinkQueue *Q, QElemType *e) 13 { 14 QueuePtr = p; 15 if (Q->front == Q->rear) return ERROR; 16 p = Q->front->next; 17 *e = p->date; 18 Q->front->next = p->next; 19 if (Q->rear == p) Q->rear = Q->front; 20 free(p); 21 return OK; 22 }
标签:
原文地址:http://www.cnblogs.com/xiaoxxmu/p/5680100.html