循环队列实现代码(环形队列),1~n报数,数到m,前面1~m出列,将m对应元素加入队尾,循环往复出队;C语言实现,完整代码,VS编译,数据结构参考代码,实用代码,函数库,通用参考代码,报数循环队列实现

/* 环形队列 实例 Cyclic Queue
* q.front->[队首][]->[][]->[][]->....[队尾][NULL];
* q.rear->.............................|
* 队空条件 q->front == q->rear
* 队满条件 (q->rear + 1)%MAXSIZE == q->front (为了方便判断队满,循环缓存区留有一个空位)
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DPRINT(x,...)   printf("%s line %d:",__FILE__,__LINE__); printf(x, __VA_ARGS__)

/* 类型定义 */
typedef int elementype; // 元素类型

#define MAXSIZE     (100+1) // 最大元素个数100,留个空位

typedef struct linkque
{
    elementype  *base;  // 循环队列缓冲区
    int front;          // 队首
    int rear;           // 队尾
} CyclicQueType;        // 循环队列类型定义

/****************************************************************************************
* 函数名称: QueInit
* 函数功能: 队列初始化
* 输入参数: q       队列头指针
* 输出参数: 无
* 返 回 值: 1 成功,<=0 失败
****************************************************************************************/
int QueInit(CyclicQueType *q)
{
    q->base = (elementype*)malloc(MAXSIZE*sizeof(elementype));   // 申请头结点
    if (!q->base)
    {
        DPRINT("owerlow\n");
        return 0;
    }
    q->front = 0;
    q->rear = 0;      // 空队列

    return 1;
}

/****************************************************************************************
* 函数名称: QueEmpty
* 函数功能: 判队列是否空
* 输入参数: q       队列头指针
* 输出参数: 无
* 返 回 值: 1队列空,0 非空
****************************************************************************************/
int QueEmpty(CyclicQueType *q)
{
    if (q->front == q->rear)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/****************************************************************************************
* 函数名称: QueAdd
* 函数功能: 入队
* 输入参数: q       队列头指针
*           e       需要入队的元素
* 输出参数: 无
* 返 回 值: > 0 入队成功,<=0 失败
* 队列已满的条件是还剩最后一个空位,(队尾+1)%MAX=队首
****************************************************************************************/
int QueAdd(CyclicQueType *q, elementype e)
{
    if ((q->rear + 1)%MAXSIZE == q->front)
    {
        DPRINT("Full error\n");
        return 0;
    }

    q->base[q->rear] = e;
    q->rear = (q->rear + 1) % MAXSIZE;

    return 1;
}

/****************************************************************************************
* 函数名称: QueDel
* 函数功能: 出队
* 输入参数: q       队列头指针
* 输出参数: 无
* 返 回 值: > 0 返回出队的元素值
****************************************************************************************/
int QueDel(CyclicQueType *q, elementype *e)
{
    if (q->front == q->rear) 
    {
        return 0;
    }
    
    *e = q->base[q->front];
    q->front = (q->front + 1) % MAXSIZE;

    return 1;
}

/****************************************************************************************
* 函数名称: QueLength
* 函数功能: 获取队列长度
* 输入参数: q       队列头指针
* 输出参数: 无
* 返 回 值: >= 0 返回队列长度
****************************************************************************************/
int QueLength(CyclicQueType *q)
{
    return (q->rear + MAXSIZE - q->front)%MAXSIZE;
}

/****************************************************************************************
* 函数名称: QueClear
* 函数功能: 清空队列
* 输入参数: q       队列头指针
* 输出参数: 无
* 返 回 值: >= 0 成功
****************************************************************************************/
int QueClear(CyclicQueType *q)
{
    if (q->base)
    {
        free(q->base);
        q->base = NULL;
    }
    q->front = 0;
    q->rear  = 0;

    return 1;
}


// 1~n报数,数到m,前面1~m出列,将m对应元素加入队尾,循环往复出队
int main(void)
{
    CyclicQueType q;
    int i,n,m,j,a;
    elementype e;

    a = QueInit(&q);        // 初始化队列
    scanf("%d %d", &n, &m); // 输入队列长度n 和 报数转折点m
    for (i = 1; i <= n; i++)
    {
        QueAdd(&q, i);      // 1~n加入队列
    }
    printf("Que len=%d\n", QueLength(&q));
#if 1
    while(!QueEmpty(&q))
    {
        for (j = 1; j < m; j++)
        {
            QueDel(&q,&e);
            printf("%d\n", e);
        }
        if (!QueEmpty(&q))
        {
            QueDel(&q,&e);
            QueAdd(&q, e);
        }
    }
#endif

    QueClear(&q);   // 清空

    return 0;
}

猜你喜欢

转载自blog.csdn.net/rabbit200808/article/details/107587284