一、队列的抽象数据类型描述
类型名:队列(Queue) 数据对象集:一个有0个或多个元素的有穷线性表 操作集:长度为MaxSize的堆栈Q∈Queue, 队列元素item∈ElementType
1.生成长度为MaxSize的空队列 Queue CreatQueue(int MaxSize); 2.判断队列Q是否已满 bool IsFullQ(Queue Q, int MaxSize); 3.将数据元素item插入队列Q中 bool AddQ(Queue Q, ElementType item); 4.判断队列Q是否已空 bool IsEmptyQ(Queue Q); 5.删除并返回队首元素 ElementType DeleteQ(Queue Q);
二、队列的顺序存储实现
1.定义
队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。 形成的数组搬过来,变成一个环,便为循环队列。 为了判断队列的空与满,循环队列仅使用n-1个数组空间 定义代码如下
typedef struct QNode *Queue;
struct QNode {
ElementType Data[MaxSize];//一维数组
int rear;//记录队列尾元素位置
int front;//记录队列头元素位置
int MaxSize;
//实际上front指向的是队列头元素下标的前一个
};
2.操作
(1)创建循环队列(CreateQueue)
Queue CreateQueue( int MaxSize ) {
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
Q->front = Q->rear = 0;
Q->MaxSize = MaxSize;
return Q;
}
(2)判断队列是否已满(IsFull)
bool IsFull( Queue PtrQ ) {//front和rear+1的取余相等时队列满
return ((PtrQ->rear+1) % PtrQ->MaxSize == PtrQ->front);
}
(3)入队列(AddQ)
入队时要判断队列是否已满
bool AddQ(Queue PtrQ, ElementType item) {
if ( IsFull(PtrQ) ) {
printf("队列满");//front和rear+1的取余相等时队列满
return false;
} else {
PtrQ->rear = (PtrQ->rear+1) % PtrQ->MaxSize;
//移动队尾rear 以取余运算来实现循环
PtrQ->Data[PtrQ->rear] = item;
return true;
}
}
(4)判断队列是否已空(IsEmpty)
bool IsEmpty(Queue PtrQ) {
return ( PtrQ->front == PtrQ->rear );
}
(5)出队列(DeleteQ)
出队时判断当前队列是否为空
ElementType DeleteQ(Queue PtrQ) {
if(IsEmpty(PtrQ)) {//rear和front相等时队列空
printf("队列空");
return false;
} else {
PtrQ->front = (PtrQ->front+1) % PtrQ->MaxSize;//移动队首front
return PtrQ->Data[PtrQ->front];
}
}
三、队列的链式存储实现
1.定义
队列的链式存储结构也可以用一个单链表实现,插入和删除操作分别在链表的两头进行。队列指针front应该指向链表头
struct Node {
ElementType Data;
struct Node * Next;
}
struct QNode {//链队列结构
struct Node *rear; //指向队尾结点
struct Node *front; //指向队头结点
};
typedef struct QNode *Queue;
Queue PtrQ;
2.操作
(1)不带头结点的链式队列初始化( CreateQueue)
Queue CreateQueue() {
Queue Q;
Q = (Queue)malloc(sizeof(struct QNode));
Q->front = Q->rear = NULL;//两个指针都为空
return Q;
}
(2)不带头结点的链式队列入队操作
bool AddQ(Queue PtrQ, ElementType item) {
struct Node *RearCell = PtrQ->rear;//指向队尾元素的指针
struct Node *Temp = (struct Node *) malloc(sizeof(struct Node));
Tmp->Data = X;
Tmp->Next = NULL;
if ( PtrQ->front == NULL ) {//队列为空 进第一个元素
PtrQ->rear = PtrQ->front = Tmp;
} else {
RearCell->Next = Tmp;
PtrQ->rear = Tmp;
}
return true;
}
(3)不带头结点的链式队列出队操作
ElementType DeleteQ(Queue PtrQ) {
struct Node * FrontCell;
ElementType FrontElem;//队首元素的值
if (PtrQ->front == NULL) {//1.先判断是否为空 为空无法进行出队操作
printf("队列空");
return ERROR;
}
FrontCell = PtrQ->front;
if(PtrQ->front == PtrQ->rear) //若队列只有一个元素 则删除后队列置为空
PtrQ->front = PtrQ->rear = NULL;
else
PtrQ->front = FrontCell->Next;
FrontElem = FrontCell->Data;
free(FrontCell); //释放被删除结点的空间
return FrontElem;
}