一、实验目的
(1)掌握队列的链接存储结构;
(2)掌握队里的操作特性;
(3)掌握基于链队的基本操作的实现方法
二、实验内容
(1)建立一个空队列;
(2)对已建立的队列进行插入、删除、取头元素等基本操作。
三、算法设计
1、入队操作
步骤
①为入队元素分配结点空间,用指针p
指向。
②将新结点数据域置为e
。
③将新结点插入到队尾。
④修改队尾指针为p
。
算法
//入队操作
Status EnQueue (LinkQueue &Q, QElemType e) {
p=new QNode;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p
return OK;
}
2、出队操作
步骤
①判断队列是否为空,若空则返回ERROR
。
②临时保存队头元素的空间,以备释放。
③修改队头指针,指向下一个结点。
④判断出队元素是否为最后一个元素,若是,则将队尾指针重新赋值,指向头结点。
⑤释放原队头元素的空间。
算法
//出队操作
Status DeQueue(LinkQueue &Q,QElemType &e) {
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
delete p;
return OK;
}
3、取队头元素
算法
//取队头元素
SElemType GetHead{LinkQueue Q) {
if(Q.front!=Q.rear)
return Q.front->next->data;
}
四、运行结果
五、代码实现
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int QElemType; //定义队列中元素类型,可调整
typedef struct Node{ //链队结点的结构
QElemType data;
struct Node *next;
}QNode,*QueuePtr;
typedef struct{ //链队结构的定义
QueuePtr front; //对头指针
QueuePtr rear; //对尾指针
}LQueue,*LinkQueue;
//初始化
int InitQueue(LinkQueue &Q){
Q = new LQueue; //为链队结构结点分配存储空间
if(!Q)
return ERROR; //存储分配失败
Q->front = Q->rear = new QNode;//为链队头结点分配存储空间
if(!Q->front)
return ERROR;
Q->front->next = NULL;//头结点指针域置空
return OK;
}
//入队
void EnQueue(LinkQueue Q,QElemType e){
QueuePtr p;
p = new QNode; //申请新结点
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
}
//出队
int DeQueue(LinkQueue Q,QElemType &e){
QueuePtr p;
if(Q->front == Q->rear)
return ERROR; //队空,出队失败
p = Q->front->next;
Q->front->next = p->next; //出队列
e = p->data;
delete p;
if(Q->front->next == NULL) //出队后链队若为空,则修改队尾指针
Q->rear = Q->front;
return OK;
}
//取头元素
int GetQueueF(LinkQueue Q,QElemType &e){
QueuePtr p;
if(Q == NULL||Q->front == Q->rear)
return ERROR;
p = Q->front->next;
e = p->data;
return OK;
}
//输出队列
void DispQueue(LinkQueue Q){
QueuePtr p = Q->front->next;
printf("链队元素为:");
if(Q->front == Q->rear){
printf("链队空!");
return;
}
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
//销毁链队
void DeStroyQueue(LinkQueue Q){
QElemType e;
while(DeQueue(Q,e)); //队列中的所有元素出队
delete Q->front; //释放头结点
delete Q; //释放队列结构结点
}
//显示菜单
void Showmenu(){
printf("\n");
printf(" --链队基本操作运算演示-- \n");
printf("*****************************\n");
printf("* 1---链队的初始化 *\n");
printf("* 2---创建链队 *\n");
printf("* 3---入队操作 *\n");
printf("* 4---出队操作 *\n");
printf("* 5---取头元素操作 *\n");
printf("* 0---退出 *\n");
printf("*****************************\n");
printf("请选择菜单号(0-5):");
}
void Queue(){
int choice,m,e;
QElemType item;
LinkQueue Q;
int flag = 0;
while(choice){
Showmenu();
scanf("%d",&choice);
switch(choice){
case 1:
printf("初始化链队操作\n");
if(InitQueue(Q)){
printf("初始化成功!\n");
flag = 1;
}
else
printf("初始化失败!\n");
break;
case 2:
if(flag){
printf("请输入入队元素个数:");
scanf("%d",&m);
for(int i = 0;i<m;i++){
e = rand()%20+1;
EnQueue(Q,e);
}
DispQueue(Q);
}
else{
printf("链队不存在,操作失败!\n");
}
break;
case 3:
if(flag){
printf("请输入入队元素:");
scanf("%d",&item);
EnQueue(Q,item);
printf("该元素已入队!\n");
DispQueue(Q);
}
else{
printf("链队不存在,操作失败!\n");
}
break;
case 4:
if(flag){
if(DeQueue(Q,item))
printf("出队元素为:%d !\n",item);
else
printf("队空!\n");
DispQueue(Q);
}
else{
printf("链队不存在,操作失败!\n");
}
break;
case 5:
if(flag){
if(GetQueueF(Q,item))
printf("队头元素为 %d !\n",item);
else
printf("队空!\n");
DispQueue(Q);
}
else{
printf("链队不存在,操作失败!\n");
}
break;
case 0:
printf("\t程序结束!\n");
DeStroyQueue(Q);
break;
default:
printf("选择错误,请重新输入!\n");
break;
}
}
}
//主函数
int main(){
Queue();
return 0;
}
作者文坛写于2020年5月14日