《数据结构》(C语言版)——单链队列――――队列的链式存储结构

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
// 用到的库文件
#include <stdio.h>  // printf();scanf()
#include <stdlib.h> // exit()
#include <malloc.h> // malloc()
#include <time.h>   // 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;
// -----单链队列――――队列的链式存储结构-----
typedef struct QNode {  // 队列结点结构
    QElemType data;     // 结点数据域
    struct QNode *next; // 结点指针域
} QNode, *QueuePtr;
typedef struct {        // 队列链式结构
    QueuePtr front;     // 队头指针
    QueuePtr rear;      // 队尾指针
} LinkQueue;

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

// 操作结果:销毁队列Q,Q不再存在。
Status DestroyQueue(LinkQueue &Q) {
    while(Q.front) {                // Q.front = NULL时,循环停止
        Q.rear = Q.front->next;
        free(Q.front);              // 释放每个数据结点的指针域
        Q.front = Q.rear;
    }
    return OK;
}// DestroyQueue

// 操作结果:把Q置为空队列。
Status ClearQueue(LinkQueue &Q) {
    while(Q.front->next) {          // Q.front->next = NULL时,循环停止
        Q.rear = Q.front->next;     // 队尾指向第一个结点
        free(Q.front);              // 释放每个数据结点的指针域
        Q.front = Q.rear;           // 队头重新指向下一个结点
    }
    Q.front->next = NULL;
    Q.front->data = NULL;
    return OK;
}// ClearQueue

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

// 操作结果:返回Q的元素个数,即队列的长度。
int QueueLength(LinkQueue Q) {
    int n = 0;
    QueuePtr p = Q.front;           // p指向队头
    while(p != Q.rear) {
        n++;
        p = p->next;
    }
    return n;
}// QueueLength

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

// 操作结果:插入元素e为Q的新的队尾元素。
Status EnQueue(LinkQueue &Q, QElemType e) {
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p->data = e;                    // 将e赋给新结点的数据域
    p->next = NULL;                 // 新插入的结点为队尾,其指针域置NULL
    Q.rear->next = p;               // 队尾元素指向新结点
    Q.rear = p;                     // 队尾指针后移
    printf("插入的队尾元素:%c\n", e);
    return OK;
}// EnQueue

// 操作结果:删除Q的队头元素,并用e返回其值。
Status DeQueue(LinkQueue &Q, QElemType &e) {
    if(Q.front == Q.rear)           // 空队列
        return ERROR;
    QueuePtr p = Q.front->next;     // p指向队头元素
    e = p->data;                    // 用e返回队头元素的值
    Q.front->next = p->next;        // 使头结点指向新的队头
    if(Q.rear == p)                 // 若只有一个结点,删除后为空队列
        Q.rear = Q.front;
    free(p);
    printf("删除的队头元素:%c\n", e);
    return OK;
}

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

int main() {
    LinkQueue Q;

    // 构造空队列
    if(InitQueue(Q)) {
        // 插入元素
        EnQueue(Q, 'A');
        EnQueue(Q, 'B');
        EnQueue(Q, 'C');
        EnQueue(Q, 'D');
        EnQueue(Q, 'E');
    }

    // 求队列长
    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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值