数据结构(实验C语言版)
队列的基本操作与应用
一、实验目的
1、掌握链式存储队列的进队和出队等基本操作
2、了解队列的应用
二、实验环境
硬件环境要求:
PC机(单机)
使用的软件名称、版本号以及模块:
VS2010或Visual C++ 6.0或Win-TC等。
三、实验内容
1、编写一个程序,实现链队的各种基本运算(假设队列中元素类型为char),并在此基础上设计一个程序完成如下功能:
(1)初始化链队q;
(2)判断链队q是否非空;
(3)依次进队元素a,b,c;
(4)出队一个元素,输出该元素;
(5)依次进链队元素d,e,f;
(6)输出出队序列;
(7)释放链队。
四、实验要求
1、用 VS2010 工具创建文件或程序,输入代码后,进行编译运行或在控制台 执行。
2、观看程序运行结果,并根据结果进行思考,对程序进行修改和总结。
【核心算法提示】
链队列存储结构:
typedef struct qnode
{
int data;
struct qnode *next;
} QNode; //链队节点类型
typedef struct
{
QNode *front, *rear;
} QuType; //链队类型
创建空队列:
Status InitQueue (LinkQueue &Q) {
// 构造一个空队列Q,队头指针和队尾指针都指向头结点)
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front) exit (OVERFLOW); //存储分配失败
Q.front->next = NULL;
return OK;
}
入队:
Status EnQueue (LinkQueue &Q, QElemType e)
{ // 插入元素e为Q的新队尾元素
p = (QueuePtr) malloc (sizeof (QNode)); //生成新结点
if (!p) exit (OVERFLOW); //存储分配失败
p->data = e; p->next = NULL; //插入队尾
Q.rear->next = p;
Q.rear = p; //修改队尾指针指向队尾
return OK;
}
出队:
Status DeQueue (LinkQueue &Q, QElemType &e)
{ // 若队列不空,则删除Q的队头元素,用 e 返回其值
if (Q.front == Q.rear) return ERROR; //判空
p = Q.front->next; e = p->data; //用e返回队头元素值
Q.front->next = p->next; //修改头指针始终指向队首元素
if (Q.rear == p) Q.rear = Q.front; //特殊情况处理空队
free (p); //释放队首结点
return OK;
}
源代码
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct qnode
{
ElemType data;
struct qnode *next;
} QNode;
typedef struct
{
QNode *front;
QNode *rear;
} LiQueue;
void InitQueue(LiQueue *&q);
void DestroyQueue(LiQueue *&q);
bool QueueEmpty(LiQueue *q);
void enQueue(LiQueue *&q, ElemType e);
bool deQueue(LiQueue *&q, ElemType &e);
void InitQueue(LiQueue *&q) //初始化队列
{
q = (LiQueue *)malloc(sizeof(LiQueue));
q->front = q->rear = NULL;
}
void DestroyQueue(LiQueue *&q) //销毁队列
{
QNode *p = q->front, *r; //p指向队头数据节点
if (p != NULL) //释放数据节点占用空间
{
r = p->next;
while (r != NULL)
{
free(p);
p = r; r = p->next;
}
}
free(p);
free(q); //释放链队节点占用空间
}
bool QueueEmpty(LiQueue *q) //判断队列是否为空
{
return(q->rear == NULL);
}
void enQueue(LiQueue *&q, ElemType e) //进队
{
QNode *p;
p = (QNode *)malloc(sizeof(QNode));
p->data = e;
p->next = NULL;
if (q->rear == NULL) //若链队为空,则新节点是队首节点又是队尾节点
q->front = q->rear = p;
else
{
q->rear->next = p; //将*p节点链到队尾,并将rear指向它
q->rear = p;
}
}
bool deQueue(LiQueue *&q, ElemType &e) //出队
{
QNode *t;
if (q->rear == NULL) //队列为空
return false;
t = q->front; //t指向第一个数据节点
if (q->front == q->rear) //队列中只有一个节点时
q->front = q->rear = NULL;
else //队列中有多个节点时
q->front = q->front->next;
e = t->data;
free(t);
return true;
}
void main()
{
ElemType e;
LiQueue *q;
printf("链队的基本运算如下:\n");
printf(" (1)初始化链队q\n");
InitQueue(q);
printf(" (2)依次进链队元素a,b,c\n");
enQueue(q, 'a');
enQueue(q, 'b');
enQueue(q, 'c');
printf(" (3)链队为%s\n", (QueueEmpty(q) ? "空" : "非空"));
if (deQueue(q, e) == 0)
printf("\t提示:队空,不能出队\n");
else
printf(" (4)出队一个元素%c\n", e);
printf(" (5)依次进链队元素d,e,f\n");
enQueue(q, 'd');
enQueue(q, 'e');
enQueue(q, 'f');
printf(" (6)出链队序列:");
while (!QueueEmpty(q))
{
deQueue(q, e);
printf("%c ", e);
}
printf("\n");
printf(" (7)释放链队\n");
DestroyQueue(q);
}