//CircularQueue.h
/*******************************************************************
顺序队列可能存在虚满的情况( 队尾元素后一位置下标到达容量值,队头元素下标
不在0,即队列的头部虽为空,但不能插入),于是出现了能处理这一缺陷的循环队列。
循环队列要求队列在逻辑上能够循环,但计算机中的存储结构却是线性的,要实现
逻辑上的循环需要依靠 " 取余% " 的方法。
循环队列的满可以通过两种方式定义:
1、以 队头元素下标 与 队尾元素后一位置下标 是否相等来判断,这一方式需要额
外维护一个flag标志来辅助确定相等时队列的状态时满还是空
2、预留队列中一个元素大小的空间,预留的空间未尾后指针所指空间,以 队尾元素
后一位置之后位置的下标 是否等于 队头元素下标 的方式(即 head == tail + 1)
来判断队列是否满,等于时为满
********************************************************************/
#ifndef _CIRCULARQUEUE_H_
#define _CIRCULARQUEUE_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 10
typedef int ElementType;
typedef struct Queue
{
ElementType *base;
int head; //队头指针
int tail; //尾后指针
}Queue;
bool InitQueue(Queue *sq);
bool EnQueue(Queue *sq, ElementType e);
void ShowQueue(Queue sq);
bool DeQueue(Queue *sq);
int length(Queue sq);
bool IsEmpty(Queue sq);
bool IsFull(Queue sq);
bool GetTop(Queue sq, ElementType *e);
void Clear(Queue *sq);
void Destroy(Queue *sq);
#endif //_CIRCULARQUEUE_H_
//CircularQueue..c
#include "CircularQueue.h"
bool InitQueue(Queue *sq)
{
ElementType *p = (ElementType *)malloc(sizeof(ElementType) *MAXSIZE);
if( NULL == p )
return false;
sq->base = p;
sq->head = sq->tail = 0;
return true;
}
bool EnQueue(Queue *sq, ElementType e)
{
if( IsFull(*sq) )
{
printf("队列已满\n");
return false;
}
sq->base[sq->tail] = e; //插入
sq->tail = (sq->tail + 1) % MAXSIZE; //更新尾指针
return true;
}
void ShowQueue(Queue sq)
{
for (int i = sq.head; i != sq.tail; i = (i + 1) % MAXSIZE)
{
printf("%d\n", sq.base[i]);
}
}
bool DeQueue(Queue *sq)
{
if( IsEmpty(*sq) )
{
printf("队列已空\n");
return true;
}
sq->head = (sq->head + 1) % MAXSIZE; //更新队头指针
return true;
}
int length(Queue sq)
{
return sq.tail > sq.head ? (sq.tail - sq.head) : (MAXSIZE - sq.head + sq.tail);
}
bool IsEmpty(Queue sq)
{
return sq.head == sq.tail;
}
bool IsFull(Queue sq)
{
return (sq.tail + 1) % MAXSIZE == sq.head;
}
bool GetTop(Queue sq, ElementType *e)
{
if( IsEmpty(sq) )
{
printf("队列已空\n");
return true;
}
*e = sq.base[sq.head];
return true;
}
void Clear(Queue *sq)
{
sq->head = sq->tail = 0;
}
void Destroy(Queue *sq)
{
Clear(sq);
free(sq->base);
sq->base = NULL;
}
//main.c
#include "CircularQueue.h"
void main()
{
Queue sq;
ElementType e;
InitQueue(&sq);
for (int i = 0; i != 15; i++)
EnQueue(&sq, i);
printf("显示\n");
ShowQueue(sq);
if (GetTop(sq, &e))
printf("队头元素为%d\n", e);
printf("出队\n");
for (int i = 0; i != 5; i++)
DeQueue(&sq);
printf("显示\n");
ShowQueue(sq);
printf("队列长度为%d\n", length(sq));
if (GetTop(sq, &e))
printf("队头元素为%d\n", e);
printf("入队\n");
for (int i = 0; i != 15; i++)
EnQueue(&sq, i * 10);
printf("显示\n");
ShowQueue(sq);
printf("队列长度为%d\n", length(sq));
printf("清除\n");
Clear(&sq);
printf("显示\n");
ShowQueue(sq);
Destroy(&sq);
system("pause");
}