約瑟夫問題(單向迴圈連結串列應用例項)
阿新 • • 發佈:2019-02-08
據說著名猶太曆史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡為止。然而Josephus
和他的朋友並不想遵從。首先從一個人開始,越過k-2個人(因為第一個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下一個人留下,這個人就可以繼續活著。問題是,給定了和,一開始要站在什麼地方才能避免被處決?Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置 ,於是逃過了這場死亡遊戲。
根據上面的問題我們分析出可以通過單向迴圈連結串列解決:
#include "StdAfx.h" #include <stdio.h> #include <stdlib.h> typedef struct node{ int data; struct node* next; }node; node* create(int n){ node* head=(node*)malloc(sizeof(node)); if(!head) return NULL; node* pTemp=head; for(int i=0;i<n;i++){ node* p=(node*)malloc(sizeof(node)); if(!p) return NULL; p->data=i+1; p->next=pTemp->next; pTemp->next=p; pTemp=p; } pTemp->next=head->next;//構造一個迴圈連結串列 pTemp=head; head=head->next;//得到第一個 free(pTemp); return head;//最後得到第一個結點 } int main(){ //約瑟夫問題 int n=41; int m=3;//第三個人就會被選出 node* head=create(n);//建立41個迴圈連結串列 node* p=head; m%=n;//取餘數 while(p!=p->next){//如果只剩下一個則自己指向自己 for(int i=1;i<m-1;i++){ p=p->next; } node* pTemp=p->next; printf("%d ",pTemp->data);//打印出來 p->next=pTemp->next; free(pTemp); p=p->next; } printf("%d ",p->data);//打印出來 return 0; }