1. 程式人生 > >用迴圈連結串列解決約瑟夫環的問題

用迴圈連結串列解決約瑟夫環的問題

約瑟夫環問題簡介

 約瑟夫環問題的原來描述為,設有編號為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 (int
i = 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 */

 

 

哈哈,初學資料結構,寫的不好的請多包容!

早點休息!晚安!