1.队列:只允许在一端插入,在另一端删除的线性表。FIFO,允许插入的是队尾,允许删除的是队头。队列删除插入操作之后不需要进行元素的移动,而是用两个下标指示出队列的位置。front指向队头元素,rear指向队尾元素的下一个位置。当front==rear时,队列是空队列。
2.循环队列:解决假溢出的问题,构造一个头尾相接的顺序存储结构的循环队列。
定义循环队列
typedef struct
{
ElemType data[MAXSIZE];
int front;
int rear;
}SqQueue;
初始化循环队列
Status InitQueue(SqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}
求循环队列的长度:rear>front时长度为rear-front; rear<front时长度为rear-front+QueueSize
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
入队出队操作:
Status Insert(SqQueue *Q, ElemType e)
{
if((Q->rear+1)%MAXSIZE == Q->front) return ERROR; //队列满,其实此时留有一个空白数组位置
Q->data[Q->rear] = e;
Q->rear = (Q->rear+1)%MAXSIZE;
return OK;
}
Status Delet(SqQueue *Q, ElemType e)
{
if(Q->front == Q->rear) return ERROR;
*e = Q->data[Q->front];
Q->front = (Q->front+1)%MAXSIZE;
return OK;
}
3.链式队列:对头指针指向链队列的头结点。
typedef struct
{
Node *front,*rear;
}LinkQueue;
入队操作:
Status Insert(LinkQueue *Q, ElemType x)
{
Node *s = (Node *)malloc(sizeof(Node));
s->data = e;
s->next = NULL;//插入到尾节点
Q->rear->next = s;
Q->rear = s;
return OK;
}
出队操作:front指向头结点,front->next指向第一个删除的节点
Status Delet(LinkQueue *Q, ElemType *x)
{
Node *p;
if(Q->front == Q->rear) return ERROR;
p= Q->front->next;//p指向第一个元素
*x = p->data;
Q->front->next = p->next;//头结点指向第二个元素
if(Q->rear == p) Q->rear = Q->front;//若对头是对尾,则删除后将rear指向头结点
free(p);
return OK;
}
循环队列和链队列的插入删除操作时间复杂度都是O(1)。