《数据结构》(C语言版)——循环队列――――队列的顺序存储结构

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
// 用到的库文件
#include   // printf();scanf()
#include  // exit()
#include  // malloc()
#include    // srand((unsigned)time(NULL));
// 函数结果状态代码
#define TRUE    1
#define FALSE   0
#define OK      1
#define ERROR   0
#define INFEASIBLE  -1
#define OVERFLOW    -2
// Status是函数的类型,其值是函数结果状态代码
typedef int Status;
// #define ElemType int  // 也可以用宏定义确定ElemType类型
typedef char QElemType;
// -----循环队列――――队列的顺序存储结构-----
#define MAXQSIZE 100    // 最大队列长度
typedef struct {        // 队列链式结构
    QElemType *base;    // 初始化的动态分配存储空间
    int front;          // 头指针,若队列不空,指向队列头元素
    int rear;           // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;

// 操作结果:构造一个空队列Q。
Status InitQueue(SqQueue &Q) {
    Q.base = (QElemType*)malloc(MAXQSIZE * sizeof(QElemType));
    if(!Q.base)                     // 存储分配失败
        exit(OVERFLOW);             // exit(-2)程序异常退出
    Q.front = Q.rear = 0;
    return OK;
}// InitQueue

// 操作结果:销毁队列Q,Q不再存在。
Status DestroyQueue(SqQueue &Q) {
    Q.front = Q.rear = 0;
    free(Q.base);
    return OK;
}// DestroyQueue

// 操作结果:把Q置为空队列。
Status ClearQueue(SqQueue &Q) {
    Q.front = Q.rear = 0;
    return OK;
}// ClearQueue

// 操作结果:若Q为空队列,返回TRUE,否则返回FALSE
Status QueueEmpty(SqQueue Q) {
    if(Q.front == Q.rear)
        return TRUE;                // 返回1
    else
        return FALSE;               // 返回0
}// QueueEmpty

// 操作结果:返回Q的元素个数,即队列的长度。
int QueueLength(SqQueue Q) {
    return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}// QueueLength

// 操作结果:若Q为非空队列,则用e返回Q的队头元素。
Status GetHead(SqQueue Q, QElemType &e) {
    if(Q.front == Q.rear)
        return ERROR;               // 空队列
    e = Q.base[Q.front];            // 取队头元素
    printf("获取的队头元素:%c\n", e);
    return OK;
}// GetHead

// 操作结果:插入元素e为Q的新的队尾元素。
Status EnQueue(SqQueue &Q, QElemType e) {
    // 少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置上”作为队列满的标志。
    if((Q.rear + 1) % MAXQSIZE == Q.front)
        return ERROR;               // 队列满
    Q.base[Q.rear] = e;             // 插入元素e
    Q.rear = (Q.rear+1)%MAXQSIZE;   // rear后移
    printf("插入的队尾元素:%c\n", e);
    return OK;
}// EnQueue

// 操作结果:删除Q的队头元素,并用e返回其值。
Status DeQueue(SqQueue &Q, QElemType &e) {
    if(Q.front == Q.rear)
        return ERROR;               // 空队列
    e = Q.base[Q.front];
    Q.front = (Q.front+1)%MAXQSIZE; // front后移
    printf("删除的队头元素:%c\n", e);
    return OK;
}

Status visit(QElemType e) {
    printf("%c -> ", e);
    return OK;
}// DeQueue
// 操作结果:从 队头到队尾,依次对Q的每个数据元素调用函数visit()。一旦vistit()失败,刚操作失败。
Status QueueTraverse(SqQueue Q, Status (*pfn_visit)(QElemType)) {
    if(Q.front == Q.rear) {
        printf("队列为空!\n");
        return ERROR;               // 空队列
    }
    int i = Q.front;                // i指向队头元素下标
    while(i != Q.rear) {
        visit(Q.base[i]);
        i = (i+1) % MAXQSIZE;
    }
    printf("\n");
    return OK;
}// QueueTraverse

int main() {
    SqQueue Q;

    // 构造空队列
    if(InitQueue(Q)) {
        // 插入元素
        for(int i=0; i<26; i++)
            EnQueue(Q, 'A' + i);
    }

    // 求队列长
    printf("队列的大小:%d\n", QueueLength(Q));

    // 返回队列的队头元素
    QElemType e;
    if(GetHead(Q, e))
        QueueTraverse(Q, visit);

    // 删除队列的队头元素
    if(DeQueue(Q, e))
        QueueTraverse(Q, visit);

    // 判空
    if(QueueEmpty(Q))
        printf("队列为空。\n");
    else
        printf("队列非空。\n");

    // 置空
    ClearQueue(Q);
    QueueTraverse(Q, visit);

    // 判空
    if(QueueEmpty(Q))
        printf("队列为空。\n");
    else
        printf("队列非空。\n");

    // 销毁
    DestroyQueue(Q);
    return 0;
}

你可能感兴趣的:(数据结构)