【練習】舞伴配對問題
阿新 • • 發佈:2018-12-25
題目:假設在週末舞會上,男士們和女士們進入舞廳時,各自排成一隊。跳舞開始時,依次從男隊和女隊的隊頭上各處一人配成舞伴。若兩隊初始人數不相同,則較長的那一對中未配對者等待下一輪舞曲。請模擬上述舞伴配對問題。
分析:該問題具有先進先出特性,可通過順序迴圈佇列儲存結構實現。假設男士和女士的記錄存放在一個數組中作為輸入,然後一次掃描該陣列的各元素,並根據性別來決定是進入男隊還是女隊。當這兩個佇列構造完成之後,一次將兩隊當前的對頭元素出隊來配成舞伴,直至某佇列變空為止。此時,若某佇列仍有等待配對者,則輸出次佇列中等待著的人數及排在對頭的等待者的名字,他(或她)將是下一輪舞曲開始時的第一個可獲得舞伴的人。
- 型別定義
#include<stdio.h>
#define QueueSize 10
typedef struct{
char name[20];
char sex; /*性別,'F'表示女性,'M'表示男性*/
}Person;
typedef Person DataType; /* 將佇列中元素的資料型別改為Person */
typedef struct Squeue{ /*順序佇列型別定義*/
DataType queue[QueueSize];
int front,rear; /*隊頭指標和隊尾指標*/
}SeqQueue;
- 函式檔案
void InitQueue(SeqQueue *SQ)
/*將順序佇列初始化為空佇列只需要把隊頭指標和隊尾指標同時置為0*/
{
SQ->front=SQ->rear=0; /*把隊頭指標和隊尾指標同時置為0*/
}
int QueueEmpty(SeqQueue SQ)
/*判斷佇列是否為空,佇列為空返回1,否則返回0*/
{
if(SQ.front==SQ.rear) /*判斷隊頭指標和隊尾指標是否相等*/
return 1; /*當佇列為空時,返回1;否則返回0*/
else
return 0;
}
int EnQueue(SeqQueue *SQ,DataType e)
/*將元素x插入到順序佇列SQ中,插入成功返回1,否則返回0*/
{
if(SQ->front==(SQ->rear+1)%QueueSize) /*在插入新的元素之前,判斷隊尾指標是否到達陣列的最大值,即是否佇列已滿*/
return 0;
SQ->queue[SQ->rear]=e; /*在隊尾插入元素x */
SQ->rear=(SQ->rear+1)%QueueSize; /*隊尾指標向後移動一個位置*/
return 1;
}
int DeQueue(SeqQueue *SQ,DataType *e)
/*刪除順序佇列中的隊頭元素,並將該元素賦值給e,刪除成功返回1,否則返回0*/
{
if(SQ->front==SQ->rear) /*在刪除元素之前,判斷佇列是否為空*/
return 0;
else
{
*e=SQ->queue[SQ->front]; /*將要刪除的元素賦值給e*/
SQ->front=(SQ->front+1)%QueueSize; /*將隊頭指標向後移動一個位置,指向新的隊頭*/
return 1;
}
}
int GetHead (SeqQueue SQ,DataType *e)
/*取隊頭元素,並將該元素賦值給e,取元素成功返回1,否則返回0*/
{
if(SQ.front==SQ.rear) /*在取隊頭元素之前,判斷順序迴圈佇列是否為空*/
return 0;
else
{
*e=SQ.queue[SQ.front]; /*將隊頭元素賦值給e,取出隊頭元素*/
return 1;
}
}
void DancePartner(DataType dancer[],int num)
/*結構陣列dancer中存放跳舞的男女,num是跳舞的人數*/
{
int i;
DataType p;
SeqQueue Mdancers,Fdancers;
InitQueue(&Mdancers);/*男士佇列初始化*/
InitQueue(&Fdancers);/*女士佇列初始化*/
for(i=0;i<num;i++){/*依次將跳舞者依其性別入隊*/
p=dancer[i];
if(p.sex=='F')
EnQueue(&Fdancers,p); /*排入女隊*/
else
EnQueue(&Mdancers,p); /*排入男隊*/
}
printf("配對成功的舞伴分別是: \n");
while(!QueueEmpty(Fdancers)&&!QueueEmpty(Mdancers)){
/*依次輸入男女舞伴名*/
DeQueue(&Fdancers,&p); /*女士出隊*/
printf("%s ",p.name);/*打印出隊女士名*/
DeQueue(&Mdancers,&p); /*男士出隊*/
printf("%s\n",p.name); /*打印出隊男士名*/
}
if(!QueueEmpty(Fdancers)){ /*輸出女士剩餘人數及隊頭女士的名字*/
printf("還有%d名女士等待下一輪舞曲.\n",DancerCount(Fdancers));
GetHead(Fdancers,&p); /*取隊頭*/
printf("%s 將在下一輪中最先得到舞伴. \n",p.name);
}
else if(!QueueEmpty(Mdancers)){/*輸出男隊剩餘人數及隊頭者名字*/
printf("還有%d名男士等待下一輪舞曲.\n",DancerCount(Mdancers));
GetHead(Mdancers,&p);
printf("%s 將在下一輪中最先得到舞伴.\n",p.name);
}
}
int DancerCount(SeqQueue Q)
/*佇列中等待配對的人數*/
{
return (Q.rear-Q.front+QueueSize)%QueueSize;
}
- 主程式
void main()
{
int i,n;
DataType dancer[30];
printf("請輸入舞池中排隊的人數:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("姓名:");
scanf("%s",dancer[i].name);
getchar();
printf("性別:");
scanf("%c",&dancer[i].sex);
}
DancePartner(dancer,n);
}
- 測試結果