吉首大学 软件学院
《数据结构与算法》实验报告
实验名称 |
(循环队列)的基本操作及应用 |
实验地点 |
3318 |
||
指导老师 |
张延亮 |
实验时间 |
2018.11.03 |
提交时间 |
2018.11.03 |
班 级 |
2017级5班 |
姓 名 |
谭路 |
学 号 |
2017401336 |
一、 实验目的 (1) 掌握队列存储结构的表示和实现方法; (2) 掌握队列的入队和出对等基本操作的算法实现; (3) 了解队列在实际问题中的简单应用 二、 实验内容 1. 问题描述: 某班有w个女生,有m个男生(w不等于m),现要开一个舞会。男女生分别编号坐在舞池的两边的椅子上。每一首舞曲开始时,一次从男生和女生中各出一人配对进入舞池跳舞,舞池允许进入的人数为k对学生(假设k的值小于w与m的值)。本曲没有成功配对者坐等下一曲找舞伴。请实际一个系统动态的现实出上述过程(本曲跳完之后,跳舞的学生走出外出重新排在原来队伍的尾部,其顺序和原来的顺序相同)。 2. 基本要求:输出第k首舞曲配对情况。 三、 实验原理及结果 #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib>
using namespace std;
typedef struct { char name[20]; char gender; }person, ElemType;
typedef struct QNode{ ElemType date; struct QNode *next; }QNode, *QNodePtr;
typedef struct { QNodePtr front; //队头指针 QNodePtr rear; //队尾指针 }LinkQueue;
//创建队列 bool InitQueue(LinkQueue &Q){ Q.front = Q.rear = new QNode; //队头队尾指针都指向新建队列 if(Q.front == NULL || Q.rear == NULL){ return false; } Q.front->next = NULL; return true; }
//销毁队列 bool DestroyQueue(LinkQueue Q){ QNode* p = new QNode; while(Q.front != Q.rear){ p = Q.front; Q.front = Q.front->next; delete p; } return true; }
//返回队列的长度 int QueueLenth(LinkQueue Q){ QNode* p = new QNode; p = Q.front; int lenth = 0; while(p != Q.rear){ lenth++; p = p->next; } }
//往队尾添加元素e bool EnQueue(LinkQueue &Q, ElemType e){ QNode *p = new QNode; p->next = NULL; p->date = e; Q.rear->next = p; Q.rear = p; return true; }
//删除队头元素,并且返回元素e bool DeQueue(LinkQueue &Q, ElemType e){ e = Q.front->next->date; Q.front = Q.front->next->next; return true; }
//遍历队列 void QueueTraverse(LinkQueue Q){ QNode* p = new QNode; p = Q.front; while(p != Q.rear){ p = p->next; cout << p->date.name << " " << p->date.gender << endl; } }
//遍历队列第k个位置 bool QueueTraverse(LinkQueue Q, int k){ QNode* p = new QNode; p = Q.front; int lenth = 0; while(p != Q.rear){ lenth++; p = p->next; if(lenth == k){ cout << p->date.name << " " << p->date.gender << endl; } } }
//返回某个位置元素的结点 QNode* FindIndexNode(LinkQueue Q, int k){ QNode* p = new QNode; p = Q.front; int lenth = 0; while(p != Q.rear){ lenth++; p = p->next; if(lenth == k){ return p; } } }
//有某个结点演变而来的链接 void ChangeQueue(LinkQueue &Q, int k){ QNode * p = FindIndexNode(Q, k); Q.rear->next = Q.front->next; Q.front->next = p->next; Q.rear = p; p->next = NULL; }
int main(){ //声明两个队列并且初始化队列 LinkQueue MQ; LinkQueue FQ; InitQueue(MQ); InitQueue(FQ);
//输入数据 cout << "请输入参加舞会的人员名单(姓名性别(F M)), 以Nobady结束" << endl; ElemType Elem; char DancerName[20]; char sex; while(1){ scanf("%s", DancerName); if(strcmp(DancerName, "Nobady") == 0){ break; } strcpy(Elem.name, DancerName); scanf("%s", &Elem.gender);
//根据性别的不同,分别加入两个队列 if(Elem.gender == 'F'){ EnQueue(FQ, Elem); } else if(Elem.gender == 'M'){ EnQueue(MQ, Elem); } }
cout << "女队的列表信息:" << endl; QueueTraverse(FQ); cout << "男队的列表信息:" << endl; QueueTraverse(MQ);
int count = 0; cout << "输入舞池每次允许进入的对数" << endl; cin >> count;
int index = 0, countTemp = count; while(countTemp --){ ChangeQueue(FQ, count); ChangeQueue(MQ, count); }
cout << "进行" << count << "回合后,舞池中的搭档:" << endl; while(index++ < count){ cout << "第" << index << "对舞伴:" << endl; QueueTraverse(FQ, index); QueueTraverse(MQ, index); } system("pause"); } /* wakaka F xiaoxi M lualux F afafga M fagafa F Nobady */ 四、 实验心得 队列和栈这两种数据结构类型都是比较常用的,栈是先进后出型,队列是先进先出行,应对不同的问题,选择合适的是数据结构去解决问题,达到最简单的解决问题。队列有顺序和链式两种,一般的顺序队列由于存在“假溢出”现象引入了循环顺序队列,此处我用的是单链表循环队列解决的问题,不用在意到底有多少人加入舞会,方便进出,并且在输出第k次舞伴配对问题上,运用自己已有的知识,实现了每一次舞伴的整体进出,不把一对舞伴当做一个元素,而把一次舞伴配对当做一个元素去解决问题。达到了自定义数据结构的要求。
|