队列是逻辑上一维的线性数据结构。所以在队列的代码实现中,很自然采用一维数组来存储队列的元素。
队列是一种先进先出的线性表,它只允许在一端(队尾)执行插入操作,而在另一端(队头)执行删除操作。
由于队列的实际操作中发生频繁的进队和出队操作,需要设立队首head和队尾tail两个变量。
head用于指示队首元素所在的位置,也就是队首元素在数组的位置下标,tail用于指示队尾元素所在的位置,也就是队尾元素在数组的位置下标。
然而实际上,tail是指示队尾元素所在位置的“下一个”位置,也就是下一个进队元素的放置位置。与简单队列很相似,循环队列也是用一个一维数组来存储队列的元素。
取模运算是循环队列的特色,它使得当tail+1等于MAXX时,可以重新变为0,让下一个进队的元素从数组“前面”部分开始存放,从而实现循环的效果。
1、利用循环队列模拟舞伴配对问题。在舞会上,男、女各自排成一队。舞会开始时。依次从男队和女队的队头各出一人配成舞伴。如果两队初始人数不等,则较长的那一队中未配对者等待下一轮舞曲。
2、假设初始男、女人数及性别已经固定,舞会的轮数从键盘输入。
3、从屏幕输出每一轮舞伴配对名单,如果在该轮有未配对的,能够从屏幕显示下一轮第一个出场的未配对者的姓名。
下面是源码:
#define _CRT_SECURE_NO_DEPRECATE
#include<cstdio>
#include<cstring>
#include<cstdlib>
const int MAXX = 100;
typedef struct Quee
{
char quee[MAXX][MAXX];
int head, tail;
int Quee_size;
}Quee;
//创建队列
void Create_Quee(Quee& p)
{
int n, i;
p.head = p.tail = 0;//初始化队列
printf("多少人跳舞呢?");
scanf("%d", &n);
p.Quee_size = n + 1;//队列元素个数+1
printf("输入每个人的名字:");
for (i = 0; i < n; i++)
scanf("%s", &p.quee[i]);
p.tail = n;//让tail指向最后一个元素
}
//判断队列是否为空
bool isEmpty(Quee p)
{
if (p.tail == p.head)
return true;
else
return false;
}
//删除当前队头元素
void DQ(Quee& p, char* str)
{
strcpy(str, p.quee[p.head]);
p.head = (p.head + 1) % p.Quee_size;//head指针指向下一个位置
}
//取走队首元素 并且不改变队头指针
void GQ(Quee p, char* str)
{
strcpy(str, p.quee[p.head]);
}
void peidui(Quee& M, Quee& F)
{
int n;
char str1[MAXX], str2[MAXX];
printf("跳几轮?");
scanf("%d", &n);
while (n--)//还有舞会就继续跳 没有就结束
{
while (!isEmpty(M))//男队还有人
{
if (isEmpty(F))//女队没人了
DQ(F, str1);
DQ(M, str1);
DQ(F, str2);
printf("%s和%s 配对成功\n", str1, str2);
}
M.head = (M.head + 1) % M.Quee_size;
if (isEmpty(F))//女队没人了
DQ(F, str1);
GQ(F, str1);
printf("下一轮第一个出场的是%s\n", str1);
}
}
int main()
{
Quee F, M;
printf("male:\n");
Create_Quee(M);
printf("Female:\n");
Create_Quee(F);
if (M.Quee_size > F.Quee_size)
peidui(F, M);
else peidui(M, F);
return 0;
}