一、ADT
只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
InitQueue(&Q)
QueueEmpty(Q)
EnQueue(&Q,x)
DeQueue(&Q,&x)
GetHead(Q,&x)
二、顺序存储
1.顺序队列
初始状态:front==rear==0
进队操作:队不满时,先送值到队尾,再将rear+1
出队操作:队不空时,先取队头元素值,再将front+1(或将后面的元素前移)
前者会造成假溢出,改用循环队列。后者会使出队操作时间复杂度为O(n)
2.循环队列
初始:front==rear==0
入队:队不满时,先送值到队尾,再将rear=(rear+1)%Maxsize
出队:队不空时,先取队头元素值,再将front=(front+1)%Maxsize
队列长度:(rear+Maxsize-front)%Maxsize
由于当前队空条件为front==rear,队满条件也为front==rear,所以需要区分队满和队空
1.牺牲一个单元来区分
队满条件(rear+1)%Maxsize==front
队空条件front==rear
2.类型中增设表示元素个数的数据成员size,队空size==0,队满size==Maxsize
3.类型中增设tag数据成员。入队时令tag=1,出队时令tag=0。tag==0时,若因删除导致front==rear,则为队空;tag==1时若因插入导致导致front==rear则为队满。
#define Maxsize 100
typedef struct {
int data[Maxsize];
int front, rear;
}SqQueue;
void InitQueue(SqQueue &Q) {
Q.front = 0;
Q.rear = 0;
}
bool isEmpty(SqQueue Q) {
if (Q.rear == Q.front) return true;
return false;
}
bool EnQueue(SqQueue &Q, int x) {
if ((Q.rear + 1) % Maxsize == Q.front) return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % Maxsize;
return true;
}
bool DeQueue(SqQueue &Q, int &x) {
if (Q.rear == Q.front) return false;
x = Q.data[Q.front];
Q.front = (Q.front + 1) % Maxsize;
return true;
}
bool GetHead(SqQueue Q, int &x) {
if (Q.rear == Q.front) return false;
x = Q.data[Q.front];
return true;
}
三、链式存储
typedef struct LNode {
int data;
struct LNode *next;
}LinkNode,*LinkList;
typedef struct {
LinkList front;
LinkList rear;
}LinkQueue;
void InitQueue(LinkQueue &Q) {
Q.front = Q.rear = (LinkList)malloc(sizeof(LinkNode));
Q.front->next = NULL;
}
bool IsEmpty(LinkQueue Q) {
if (Q.front == Q.rear) return true;
return false;
}
void EnQueue(LinkQueue &Q, int x) {
LinkList s = (LinkList)malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
}
bool DeQueue(LinkQueue &Q, LinkList &x) {
if (Q.front == Q.rear) return false;
x = Q.front->next;
Q.front->next = x->next;
if (Q.rear == x) {
Q.rear = Q.front;
}
return true;
}
bool GetHead(LinkQueue Q, LinkList &x) {
if (Q.front == Q.rear) return false;
x = Q.front->next;
return true;
}