用迴圈連結串列解決約瑟夫環的問題
阿新 • • 發佈:2018-11-01
約瑟夫環問題簡介
約瑟夫環問題的原來描述為,設有編號為1,2,……,n的n(n>0)個人圍成一個圈,從第1個人開始報數,報到m時停止報數,報m的人出圈,再從他的下一個人起重新報數,報到m時停止報數,報m的出圈,……,如此下去,直到所有人全部出圈為止。當任意給定n和m後,設計演算法求n個人出圈的次序。 稍微簡化一下。
問題描述:n個人(編號0~(n-1)),從0開始報數,報到(m-1)的退出,剩下的人繼續從0開始報數。求勝利者的編號。
解題思路
將每個人的編號作為結點值,因為報數是迴圈著來的,故可以利用迴圈連結串列。
因為最後只有一個人獲勝,所以篩選的次數為n-1次,裡面的每次迴圈m次,表示迴圈到的第m個人淘汰。
程式碼及執行截圖
#include<iostream> #include<cstdio> using namespace std; struct node { int value; struct node *next; }; int n, m;//共n個人,報數報到m的人淘汰 //建立迴圈連結串列 struct node *init() { struct node *h = NULL; struct node *t = NULL; struct node *p = NULL; for (inti = 1; i <= n; ++i) { p = (struct node*)malloc(sizeof node); if (i == 1) { //給第一個節點賦值 h = p; t = h; t->next == NULL; } else if (i == n) { //如果是最後一個結點的時候,前面的操作都是一樣的,就把最後結點的next指向首元結點 t->next = p; t = p; t->next = h; //把最後結點的next指向首元結點 } else { //一般的連結串列建立過程 t->next = p; t = p; t->next == NULL; } cin >> t->value; } return h; } int main() { //輸入總人數以及報數的數目 while (cin >> n >> m) { struct node *t = NULL; struct node *p = NULL; t=init(); //建立迴圈連結串列 //模擬報數的過程 for (int i = 0; i < n - 1; ++i) { for(int j = 1; j < m; ++j) { p = t; t = t->next; } cout << "出列的人是" << t->value << endl << endl; p->next = t->next; free(t); t = p->next; } cout << "獲勝的人是" << t->value; } } /* 8 3 1 2 3 4 5 6 7 8 */
哈哈,初學資料結構,寫的不好的請多包容!
早點休息!晚安!