1、队列的定义
队列(Queue):也是运算受限的线性表。是一种先进先出(First In First Out ,简称FIFO)的线性表。只允许在表的一端front进行插入,而在另一端rear进行删除。 队首(front) :允许进行删除的一端称为队首。 队尾(rear) :允许进行插入的一端称为队尾。 例如:排队购物。操作系统 中的作业排队。先进入队列的成员总是先离开队列。
队列中没有元素时称为空队列。在空队列中依次加入元素a1, a2, …, an之后,a1是队首元素,an是队尾元素。显然退出队列的次序也只能是a1, a2, …, an ,即队列的修改是依先进先出的原则进行的,如图所示。
2 、队列的抽象数据类型定义 ADT Queue{ 数据对象:D ={ ai|ai∈ElemSet, i=1, 2, …, n, n >= 0 }
数据关系:R = {<ai-1, ai> | ai-1, ai∈D, i=2,3,…,n } 约定a1端为队首,an端为队尾。 基本操作 : Create():创建一个空队列; EmptyQue():若队列为空,则返回true ,否则返回flase ;
FullQue();若队列为满,则返回true ,否则返回flase ; ⋯⋯ InsertQue(x) :向队尾插入元素x; DeleteQue(x) :删除队首元素x; } ADT Queue
3、队列的表示和实现
队列可以由三种方式实现:静态数组队列、动态数组队列和链式队列。
(1)静态数组队列(循环数组队列实现)
循环队列可以更简单防止伪溢出的发生,但队列大小是固定的。 #define MAX_QSIZE 5 /* 最大队列长度+1 */ typedef struct { QElemType *base; int front; int rear; }SqQueue; void InitQueue(SqQueue *Q) { Q->base=malloc(MAX_QSIZE*sizeof (QElemType)); if (!Q->base) exit(OVERFLOW); Q->front=Q->rear=0; } void DestroyQueue(SqQueue *Q) { if (Q->base) free(Q->base); Q->base=NULL; Q->front=Q->rear=0; } void ClearQueue(SqQueue *Q) { Q->front=Q->rear=0; } Status QueueEmpty(SqQueue Q) { if (Q.front==Q.rear) return TRUE; else return FALSE; } int QueueLength(SqQueue Q) { return (Q.rear-Q.front+MAX_QSIZE)%MAX_QSIZE; } Status GetHead(SqQueue Q,QElemType *e) { if (Q.front==Q.rear) return ERROR; *e=Q.base[Q.front]; return OK; } Status EnQueue(SqQueue *Q,QElemType e) { if ((Q->rear+1)%MAX_QSIZE==Q->front) return ERROR; Q->base[Q->rear]=e; Q->rear=(Q->rear+1)%MAX_QSIZE; return OK; } Status DeQueue(SqQueue *Q,QElemType *e) { if (Q->front==Q->rear) return ERROR; *e=Q->base[Q->front]; Q->front=(Q->front+1)%MAX_QSIZE; return OK; } void QueueTraverse(SqQueue Q, void (*vi)(QElemType)) { int i; i=Q.front; while (i!=Q.rear) { vi(Q.base[i]); i=(i+1)%MAX_QSIZE; } printf("\n" ); }
(2)动态数组队列
(3)链式队列