1. 程式人生 > >對有n個人圍成的一個圓圈進行按報數規則全部取數出列

對有n個人圍成的一個圓圈進行按報數規則全部取數出列

設有n個人圍成一個圓圈,現從第s個人開始報數,數到第m的人出列,然後從出列的下一個人重新開始報數,數到第m個人再出列,如此反覆,直到所有的人全部出列為止。對於任意給定的n,s,m,求按出列次序得到的n個人員的序列。

首先,建立一個迴圈連結串列,這裡預設頭指標中的data為1,即為n個人中的第一個人

typedef int elemtype;
typedef struct node
{
elemtype data;
struct node *next;
}LinkList;

LinkList * Create()
{ LinkList * head;
LinkList *p,*tail;
elemtype x;
head=(LinkList *)malloc(sizeof(LinkList));
if(head==NULL)return head;

head->data=1;
head->next=head;
tail=head;
printf("請輸入資料,從2開始,輸入0為結束:\n");
scanf("%d",&x);
while(x!=0)
{
    p=(LinkList *)malloc(sizeof(LinkList));
    if(p==NULL)return head;
    p->data=x;
    tail->next=p;
    tail=p;
    scanf("%d",&x);

}
tail->next=head;
return head;}

出列演算法:
第一:找到第s個報數的人:
LinkList * Find(LinkList *head,int s)
{
LinkList *p=head;
int count=1;
while(p)
{
if(count==s)
break;
else
{
p=p->next;
++count;
}
}
return p;}
第二:找到第m個人出列,並將報數起點設為m的下一個人:
int OutPut(LinkList *head,int m)
{

//迴圈做法
LinkList *p=head,*q;
if(p==NULL)return -1;
int i;
while(p->data!=p->next->data)
{
    for(i=1;i<m-1;i++)
        p=p->next;
    q=p->next;//記錄取出點
    printf("\t%d",q->data);
    p->next=q->next;
    free(q);//刪除取出點
    p=p->next;//報數點
}
printf("\t%d",p->data);
return 0;}

主函式:

int main(){
LinkList * head=Create();
LinkList *p=Find(head,2);
OutPut(p,2);
printf(“\n”);
return 0;}