本周的作業還算挺好玩。。約瑟夫生死游戲嘛。
老師要抽簽選擇每個組對應的數據結構。結果寶寶抽到了單鏈表。。。。
一、項目簡介
約瑟夫生者死者游戲的大意是:30個旅客同乘一條船,因為嚴重超載,加上風高浪大,危險萬分;因此船長告訴乘客,只有將全船一半的旅客投入海中,其余人才能幸免遇難。無奈,大家只得同意這種辦法,並議定30個人圍成一圈,由第一個人開始,依次報數,數到第9人,便把他投入大海中,然后從他的下一個人數起,數到第9人,再將他投入大海,如此循環,直到剩下15個乘客為止。問哪些位置是將被扔下大海的位置。
二、設計思路
約瑟夫環問題是算法設計中的一個經典問題,是順序編號的一組n個人圍坐一圈,從第1個人按一定方向順序報數,在報到m時該人出列,然后按相同方法繼續報數,直到所有人出列。設計算法求約瑟夫環中人員的出列順序。
線性表、隊列是一種常用的數據結構,有順序和鏈式兩種存儲結構,在實際中應用十分廣泛,而鏈表又分為單鏈表和循環鏈表,隊列又分為鏈式隊列和循環隊列。這些數據結構都可用來解決約瑟夫環問題。
三、 基本要求
1、選擇合適的存儲結構,建立線性表;
2、利用單鏈表求解約瑟夫環問題;
四、測試數據
約瑟夫環的開始位置、長度、報數可以從鍵盤輸入合法數據,或者隨機生成。
代碼如下:
我的數據是隨機生成滴。
#include <cstdio> #include <ctime> #include <cstdlib> int kk=0; int ll; typedef struct people { int num; }PEO; typedef struct Node { PEO data; struct Node * next; }Node; Node *InitList(Node *L)//初始化單鏈表 { L=(Node *)malloc(sizeof(Node)); L->next=NULL; return L; } void CreateFormTail(Node *L)//尾插法 { Node *s,*r; r=L; int aa=30-ll+1+1; for(int i=1;i<=30;i++){ s=(Node *)malloc(sizeof(Node)); s->data.num=aa; r->next=s; r=s; if(i==30){ r->next=NULL; } if(aa==30) aa=1; else aa++; } } void Printf(Node *L) { int q=0; Node *p=L->next; while(p!=NULL) { q++; printf("%d\n",p->data.num); p=p->next; } printf("單鏈表長度為%d\n",q); } void sou(Node *L) { Node *s,*r,*pre; r=L; s=r->next; for(int i=1;i<=30;i++){ if(s->data.num==1) break; else r=r->next; s=r->next; } printf("被丟下水的報數按順序為\n"); while(kk<15){ for(int j=1;j<9;j++){ r=r->next; s=r->next; if(s->next==NULL){ s->next=L->next; } if(r->next==NULL){ r->next=L->next; } } printf("%d\n",s->data.num); s=s->next; pre=r->next; r->next=s; free(pre); kk++; } } int main() { srand(time(NULL));//初始化隨機化種子 ll=rand()%30+1; printf("第%d個人從1開始報數\n",ll); printf("本題條件30個人從1開始數,數到第9個人就丟下水,要丟下去15個人\n"); Node *L=NULL; L=InitList(L); CreateFormTail(L); Printf(L); sou(L); return 0; }