(演算法)C語言模擬約瑟夫環問題
阿新 • • 發佈:2018-12-11
約瑟夫環問題描述
m個人圍坐一圈,每人持有一個數字,從第一個人開始從1報數,報到n(第一輪n任意給定)的人出圈,將n改為這個出圈的人所持有的數字,下個人開始從1報數,繼續報到n的人出列;依次類推直到所有人出圈。
C語言模擬該過程演算法
這裡採用帶有尾結點的迴圈單向連結串列儲存玩家資訊,p和pre兩個指標分別指向報數結點和該結點的直接前驅,並同步移動n-1次,刪除p指向的結點直至連結串列為空即可。
具體程式碼
#include<stdio.h> #include<stdlib.h> typedef struct node{ int id;//玩家編號 int pw;//玩家持有的數字 struct node *next; }node,*LinkList; /* 用帶頭結點的尾插法建立有n個結點的迴圈連結串列,並返回尾結點 */ LinkList CreateList(LinkList head,int n){ head->next = NULL;//頭結點 head->id = 0; node *r = head;//工作指標,跟隨最後一個結點 for(int i=0;i<n;i++){ node *S = (node*)malloc(sizeof(node)); S->id = i+1; printf("input player%d's password:\n",i+1); scanf("%d",&S->pw); r->next = S; r = S; } r->next = head->next;//最後一個結點指向頭結點; return r; } void play(LinkList tail,int sum,int pw){ if(sum<1) return; else{ LinkList pre = tail; LinkList p = tail->next; int n = (pw%sum==0)?sum:pw%sum;//一輪中最少步數 while(--n){ pre = p; p = p->next; } pre->next = p->next; int newPw = p->pw; printf("player%d out!\n",p->id); p = p->next; play(pre,--sum,newPw); } } void main(){ printf("input sum:\n"); int sum ; scanf("%d",&sum); LinkList tail = CreateList((LinkList)malloc(sizeof(node)),sum); printf("input initPW:\n"); int pw ; scanf("%d",&pw); play(tail,sum,pw); }