c语言 循环队列实现舞伴匹配

题目:

循环队列的应用:舞伴配对
1.在舞会上男女各自排成一队,舞会开始时每一次从男队和女队的对头各出一人配成舞伴,
直到某队为空,如果两队初始人数不等,则较长的那一队中未配对者等待下一轮舞曲。
某轮舞毕,则舞者按该轮出序,重入各自队列。
2.假设初始男女人数分别为 11 人和 8 人,舞会三轮,试模拟解决上述舞伴配对问题,
3.要求从屏幕输出每一轮舞伴配对名单,如果在该轮有没有配上对的,能够从屏幕显示下
一轮第一个出场的未配对者的姓名。

/*队列从尾部插入头部出*/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100   //最大队列长度
#define OVERFLOW -2
#define OK 1
typedef int status;
typedef struct{
    char *name;    //初始化动态分配存储空间
    int front;    //头指针,若队列不空,指向队列头元素
    int rear;    //尾指针,若队列不空,指向队列尾元素的下一位置
}SqQueue;

/*初始化构造空队列*/
status InitQueue (SqQueue *Q){
    Q->name = (char *)malloc(MAXSIZE*sizeof(char));    //构造空队列
    if(!Q->name)exit (OVERFLOW);    //分配失败
    Q->front = Q->rear = 0;       //空时头指针和尾指针相等且为0
    return OK;
}

/*入队*/
status EnQueue (SqQueue *Q,char e){
    //插入新元素e为Q新队尾元素
    if((Q->rear+1)%MAXSIZE == Q->front) return -1;//头指针大于尾指针,即进入下一轮(因为循环链表的问题导致的错误)
    Q->name[Q->rear]=e;     //用头指针返回e值
    Q->rear=(Q->rear+1)%MAXSIZE;     //头指针向前一位
    return 1;
}

/*出队*/
status DeQueue (SqQueue *Q,char *e){
    //队列不空则删除Q头元素并用e返回,否则错误
    if(Q->front == Q->rear) return -1;
    *e = Q->name[Q->front];
    Q->front = (Q->front+1)%MAXSIZE;
    return 1;
}

/*舞伴匹配算法原始版*/
//注意此处算法内部并没有调用出栈和入栈算法
int DancePartner0(SqQueue *a,SqQueue *b){
    int j=1;      //用于标记进行了几次舞蹈
    printf("1 dance chance:\n",j);     //第一次配对开始
    while(j<=3)
    {//当配对次数在三次以内执行以下操作
        printf("%c<-->",a->name[a->front]);    //打印front指针所指的值
        a->front = (a->front+1)%8;       //打印完毕front后移一位,其中%8为a队列队长
        printf("%c\n",b->name[b->front]);      //同理对b队列执行下列操作
        b->front = (b->front+1)%11;
        if(a->front==0)     //若front为0时,即进入下一次循环队列时
        {
            printf("%d dance end\n",j);    //此次配对完毕
            printf("%c will be the first to appear\n",b->name[b->front]);
            j++;      //进入下一次的配对
            printf("%d dance chance:\n",j);
        }
    }
} 

/*舞伴匹配算法改进版*/
//调用了入队和出队函数,通过打印出队元素返回的队头元素来实现,同时用两个空队临时按顺序储存出队元素,当出队完成重新入原队保持了先出先入的顺序
//不足:多用了两个队列临时储存出队元素,增加了程序运行时的内存空间
int DancePartner1(SqQueue *a,SqQueue *b){
    char e,w;      //用于出队时返回了值
    int j=1,i;      //j用于标记配对了几轮,i用于记录男女匹配对数
    SqQueue c,d;    //用于临时储存已配对完成了元素
    InitQueue(&c);
    InitQueue(&d);
    while(j<=3)   //要完成三轮配对
    {
        printf("the %d match start:\n",j);
        for(i=0;i<8;i++)
        {
            DeQueue(a,&e);      //注意调用格式!!!
            printf("%c<-->",e);   //打印出队元素
            EnQueue(&c,e);    //同时另外存储出队元素并按顺序入队
            DeQueue(b,&w);     //同理
            printf("%c\n",w);
            EnQueue(&d,w);
        }//一个for循环为一轮配对

    //各自重新入队,为下一次配对做准备
        for(i=0;i<8;i++)
        {
            DeQueue(&c,&e);    //删除临时队列c并对其中元素重新入a队
            EnQueue(a,e);
            DeQueue(&d,&w);    //下两行代码同理
            EnQueue(b,w);
        }
        printf("the %d dance end...\n",j);
        printf("%c will be the first person matching in the next time...\n",b->name[b->front]);   //打印下一轮第一个出场的未配对者的姓名
        printf("\n");
        j++;
    } 
}

/*舞伴匹配算法最终版*/
//调用了入队和出队函数,通过打印出队元素返回的队头元素来实现,同时对该元素重新入队即插入到末位
int DancePartner(SqQueue *a,SqQueue *b){
    char e,w;      //用于出队时返回了值
    int j=1,i;      //j用于标记配对了几轮,i用于记录男女匹配对数
    SqQueue c,d;    //用于临时储存已配对完成了元素
    InitQueue(&c);
    InitQueue(&d);
    while(j<=3)   //要完成三轮配对
    {
        printf("the %d match start:\n",j);
        for(i=0;i<8;i++)
        {
            DeQueue(a,&e);      //注意调用格式!!!
            printf("%c<-->",e);   //打印出队元素
            EnQueue(a,e);      //出队元素重新入队到末位
            DeQueue(b,&w);     //同理
            printf("%c\n",w);
            EnQueue(b,w);
        }//一个for循环为一轮配对
        printf("the %d match end...\n",j);
        printf("%c will be the first person matching in the next time...\n",b->name[b->front]);   //打印下一轮第一个出场的未配对者的姓名
        printf("\n");
        j++;
    } 
}
/*主函数中生成一个队列,调用舞伴匹配算法时要求输入指针(*,*),因此要加&;而匹配算法里调用出队算法时要求的是指针(*,*),而匹配算法中输入的时候已经是指针了,所以不用再加&,而新生成的char型e则要加&;但入队函数要求调用的是(*, ),两个变量都不用加&。*/

int main()
{
    SqQueue F,M;   //生成F女士队列与M男士队列
    int i,j;
    InitQueue(&F);     //对队列初始化
    InitQueue(&M);
    char a[11]={"abcdefghijk"};    //给男队列元素起名
    char b[8]={"opqrstuv"};     //给女队列元素起名
    for(i=0;i<11;i++)     //用循环语句把元素入栈
        EnQueue(&M,a[i]);
    for(j=0;j<8;j++)
        EnQueue(&F,b[j]);
    DancePartner(&F,&M);    //舞伴配对
}

  • 3
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值