队列的定义:
队列是只允许在一端插入操作,而在另一端进行删除操作的线性表,它的特点是“先进先出”,例如键盘对电脑的输入,就是采用类似队列的存储方式。
队列的存储结构:
栈的存储方式分为顺序存储和链式存储,由于顺序存储的时间复杂度为o(n),可以用循环队列来提升存储的性能
循环队列:
在队列中,入队时只需要在队尾追加一个元素,此时的时间复杂度是o(1),但在进行出队操作时需要将所有元素都向前移动一位,此时的时间复杂度为o(n),因此可以采用循环队列的形式,也就是以头尾相接的循环来解决假溢出,这将大大提升性能
循环队列顺序存储的基本操作:
- InitQueue(*Q):初始化队列,建立一个最大空间为100空队列Q
- ClearQueue(*Q):清空队列Q
- QueueEmpty(*Q):判断队列Q是否为空
- GetHead(*Q,*e):如果队列Q存在且非空,用e返回队头Q的队头元素
- EnQueue(*Q,e):如果队列Q存在,插入新元素e到队列Q中成为队尾元素,入队操作
- DeQueue(*Q,*e):删除队列Q中的队头元素,并用e返回它的值,出队操作
- QueueLength(*Q):返回队列Q的长度
- DestroyQueue(*Q):销毁队列
在部分函数中并没有传入指针变量,这点可以稍微注意一下
定义结构体:
#include <stdio.h>
#include <stdlib.h>
#define ok 1
#define error 0
#define true 1
#define false 0
#define max_size 100
typedef int statu;
typedef int datatype; //存储的数据类型为int;
typedef struct Queue
{
datatype *data;
int head;//头指针
int tail;//尾指针,指向队尾元素的下一个位置
} queue;
初始化:InitQueue(*Q)
int InitQueue(queue *Q)
{
Q->data=(datatype*)malloc(sizeof(datatype)*max_size);
Q->head=Q->tail=0;
return ok;
}
清空队列:ClearQueue(*Q)
void ClearQueue(queue *Q)
{
Q->head=Q->tail=0;
}
队列判空:QueueEmpty(*Q)
statu QueueEmpty(queue *Q)
{
if(Q->head==Q->tail)
{
return true;
}
return false;
}
返回队头元素:GetHead(*Q,*e)
statu GetHead(queue *Q,datatype *e)
{
if(Q->tead==Q->tail)
{
return error;
}
*e=Q->data[Q->head];
return ok;
}
入队:EnQueue(*Q,e)
statu EnQueue(queue *Q,datatype e)
{
if(Q->tail+1)%max_size==Q->head)
{
return error;
}
Q->data[Q->tail]=e;
Q->tail=(Q->tail+1)%max_size;
return ok;
}
出队:DeQueue(*Q,*e)
statu DeQueue(queue *Q,datatype*e)
{
if(Q->tead==Q->tail)
{
return error;
}
*e=Q->data[Q->head];
Q->head=(Q->head+1)%max_size;
return ok;
}
返回队列长度:QueueLength(*Q)
statu QueueLength(queue *Q)
{
return (Q->tail-Q->head+max_size)%max_size;
}
销毁队列:DestroyQueue(*Q)
void DestroyQueue(queue *Q)
{
while(Q->data)
{
free(Q->data);
}
Q->data=0;
Q->head=Q->tail=0;
}