数据结构与算法(7)循环队列

队列

队列是一种和栈相反的数据结构,属于FIFO(First In, First Out)的线性表,我们只能够在队列的一端进行插入在另一端进行删除元素的操作。允许插入的一端称为队尾, 允许删除的一端称为队头。在程序设计中,典型的队操作是操作系统中的作业排队。

循环队列

将顺序队列臆造出一个环状的空间,称之为循环队列。如图

数据结构与算法(7)循环队列_第1张图片

注意这里少用一个元素空间是为了区别队列是空还是满, 因为如果front中存储数据的话,front==rear不足以判断队是空还是满

还有一种方式是设置标志位来区分

循环队列的结构

front为队首指针
rear为队尾指针

typedef char Elemtype;

typedef struct{
    Elemtype *base;
    int front;
    int rear;
}SqQueue;

循环队列的基本操作实现

  • 初始化循环队列
/*
初始化循环队列
*/
Status InitSqQueue(SqQueue *q)
{
    q->base = (Elemtype *)malloc(sizeof(Elemtype)* DATA_MAX_SIZE);
    if (!q->base)
        return ERROR;
    q->front = q->rear = 0; 

    return OK;
}
  • 销毁循环队列
/*
销毁队列
*/
Status DestoryQueue(SqQueue *q)
{
    free(q->base);
    q->base = NULL;
    q->front = q->rear = 0;

    return OK;
}
  • 计算队列长度
/*
队列的长度
*/
int SqQueueLength(SqQueue q)
{
    return (q.rear - q.front + DATA_MAX_SIZE) % DATA_MAX_SIZE;
}
  • 入队
/*
入队
*/
Status EnSqQueue(SqQueue *q, Elemtype e)
{
    if ((q->rear + 1) % DATA_MAX_SIZE == q->front)//队满检测
        return ERROR; 

    q->base[q->rear] = e;
    q->rear = (q->rear + 1) % DATA_MAX_SIZE;//确保指针rear的取值范围在0-DATA_MAX_SIZE中

    return OK;
}
  • 出队
/*
出队
*/
Status DeSqQueue(SqQueue *q, Elemtype *e)
{
    if (q->front == q->rear)
        return ERROR;

    *e = q->base[q->front];
    q->front = (q->front + 1) % DATA_MAX_SIZE;
    return OK;
}

测试使用代码

#if 0
循环队列,
使用front和rear
少使用一个元素空间,约定"队列指针在队尾指针的下一位置(环状的下一位置上)作为队列呈满状态标识"
#endif

#include 
#include 

#define DATA_MAX_SIZE 10

#define OK 1
#define ERROR 0

#define TRUE 1
#define FALSE 0

typedef int Status;
typedef char Elemtype;

typedef struct{
    Elemtype *base;
    int front;
    int rear;
}SqQueue;

/*
初始化循环队列
*/
Status InitSqQueue(SqQueue *q)
{
    q->base = (Elemtype *)malloc(sizeof(Elemtype)* DATA_MAX_SIZE);
    if (!q->base)
        return ERROR;
    q->front = q->rear = 0; 

    return OK;
}
/*
销毁队列
*/
Status DestoryQueue(SqQueue *q)
{
    free(q->base);
    q->base = NULL;
    q->front = q->rear = 0;

    return OK;
}

/*
入队
*/
Status EnSqQueue(SqQueue *q, Elemtype e)
{
    if ((q->rear + 1) % DATA_MAX_SIZE == q->front)//队满检测
        return ERROR; 

    q->base[q->rear] = e;
    q->rear = (q->rear + 1) % DATA_MAX_SIZE;//确保指针rear的取值范围在0-DATA_MAX_SIZE中

    return OK;
}
/*
出队
*/
Status DeSqQueue(SqQueue *q, Elemtype *e)
{
    if (q->front == q->rear)
        return ERROR;

    *e = q->base[q->front];
    q->front = (q->front + 1) % DATA_MAX_SIZE;
    return OK;
}
/*
队列的长度
*/
int SqQueueLength(SqQueue q)
{
    return (q.rear - q.front + DATA_MAX_SIZE) % DATA_MAX_SIZE;
}


int main()
{
    SqQueue q;
    Elemtype e;
    printf("初始化循环队列\n");
    InitSqQueue(&q);
    printf("开始入队a, b, c\n");
    if (EnSqQueue(&q, 'a') == ERROR)
        printf("错误:队满\n");
    if (EnSqQueue(&q, 'b') == ERROR)
        printf("错误:队满\n");
    if (EnSqQueue(&q, 'c') == ERROR)
        printf("错误:队满\n");
    if (EnSqQueue(&q, 'd') == ERROR)
        printf("错误:队满\n");
    if (EnSqQueue(&q, 'e') == ERROR)
        printf("错误:队满\n");

    printf("开始出队\n");
    if (DeSqQueue(&q, &e) == ERROR)
        printf("错误:队空\n");
    printf("出队: %c\n", e);
    if (DeSqQueue(&q, &e) == ERROR)
        printf("错误:队空\n");
    printf("出队: %c\n", e);
    if (DeSqQueue(&q, &e) == ERROR)
        printf("错误:队空\n");
    printf("出队: %c\n", e);

    printf("销毁队列\n");
    DestoryQueue(&q);

    system("pause");
    return 0;
}


你可能感兴趣的:(数据结构与算法(7)循环队列)