循环队列因为只有数据指针,头、尾下标,无法存储其总容量大小,所以无法扩容,可扩容队列的结构体中还需要有int变量存储其总容量,然后用realloc()扩容。
其他大部分代码与循环顺序队列一样,在出队、判满、获取有效个数时注意把MAXSIZE换成pq->queuesize(当前总容量)就行。
结构体定义:
typedef int QElemType;
#define MAXSIZE 5//初始大小为5
typedef struct
{
QElemType * base;
int front;
int rear;
int queuesize;//总容量
}DQueue, * PDQueue;
初始化
void InitQueue(PDQueue pq)
{
assert(pq);
if (!pq)
return;
pq->queuesize = MAXSIZE;
pq->base = (QElemType*)malloc(sizeof(DQueue));
assert(pq->base != NULL);
pq->front = NULL;
pq->rear = NULL;
}
销毁
void Destroy(PDQueue pq)
{
free(pq->base);
pq->base = NULL;
pq->front = pq->rear = 0;
}
清空数据
void Clear(PDQueue pq)
{
pq->front = pq->rear = 0;
}
有效数据个数
由于数组可能扩容,所以要对pq->queuesize取余,不能像定长的循环顺序队列一样%MAXSIZE。
判满同理
int GetLength(PDQueue pq)
{
assert(pq != NULL);
if (pq == NULL)
return -1;
int len = (pq->rear - pq->front + (pq->queuesize)) % (pq->queuesize);
return len;
}
判空判满
//判空
bool IsEmpty(PDQueue pq)
{
return pq->front == pq->rear;
}
//判满
static bool IsFull(PDQueue pq)
{
return (pq->rear + 1) % (pq->queuesize) == pq->front;
}
扩容
如果数据满了,调用此函数
static bool Inc(PDQueue ps)
{
assert(ps != NULL);
ps->base = (QElemType*)realloc(ps->base, sizeof(QElemType) * ps->queuesize * 2);//扩容用realloc
assert(ps->base != NULL);
if (ps->base == NULL)
return false;
ps->queuesize *= 2;//扩容到两倍
return true;
}
入队/获取对头元素/出队
//入队
bool Push(PDQueue pq, int val)
{
if (IsFull(pq))
Inc(pq);
pq->base[pq->rear] = val;
pq->rear = (pq->rear + 1) % (pq->queuesize);
return true;
}
//获取队头的值,但不删除
bool GetHead(PDQueue pq, QElemType* rtval)
{
if (IsEmpty(pq))
return false;
*rtval = pq->base[pq->front];
return true;
}
//获取队头的值,且删除
bool Pop(PDQueue pq, QElemType* rtval)
{
if (IsEmpty(pq))
return false;
*rtval = pq->base[pq->front];
pq->front = (pq->front + 1) % (pq->queuesize);
return true;
}