/* 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;
}
《数据结构》(C语言版)——单链队列――――队列的链式存储结构
最新推荐文章于 2022-07-28 20:52:58 发布