約瑟夫環問題的鍊錶實現

2021-07-13 10:54:23 字數 1653 閱讀 6206



據說著名猶太歷史學家 josephus有過以下的故事:在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了乙個自殺方式,41個人排成乙個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下乙個重新報數,直到所有人都自殺身亡為止。然而josephus 和他的朋友並不想遵從。首先從乙個人開始,越過k-2個人(因為第乙個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下乙個人留下,這個人就可以繼續活著。問題是,給定了和,一開始要站在什麼地方才能避免被處決?josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。

後來人們把這個問題進行了簡化:n個人圍成一圈,從第1個人開始報數,將報第m個數的人殺掉,然後從第m+1個人又從1開始報數,報第m個數的人殺掉,如此迴圈······  最後剩下乙個,其餘人都將被殺掉。例如n=6,m=5,被殺掉的順序是:5,4,6,2,3。最後能活下來的人是 1。這個問題就是經典的約瑟夫環問題,有時也稱約瑟夫置換或丟手絹問題。

是乙個經常出現在電腦科學和數學中的問題。

約瑟夫問題並不難,但求解的方法很多;題目的變化形式也很多。這裡給出一種用鍊錶實現的方法

我們用乙個單迴圈鍊錶來模擬圍成一圈的n個人,用結構體來構**員資訊,結構體中儲存兩個成員,其中乙個為指向下乙個人的指標,已構成環形鏈,另乙個成員記錄人員所處的位置序號。殺掉乙個人就刪除乙個節點的資訊。如此迴圈,直到只剩下乙個人,即活下來的那個人。

具體實現**如下,希望和大家一起交流學習。

#define  _crt_secure_no_warnings

#include#includetypedef int datatype;

typedef struct node

node, *pnode;

pnode cur = null;//當前節點

pnode pre = null;//當前結點的前乙個節點

pnode head = null;//頭節點

pnode createnode( datatype n)//用單迴圈鍊錶建立約瑟夫環

else

if (head == null)

else

pre = cur;

} cur ->next = head;//鍊錶尾節點指向頭節點形成環

return head;

}

void josephcircle(datatype num, datatype count)

printf("第%d個出局的人是第%d 位\n", i, cur->data);

pre->next = cur->next;

free(cur);

cur = pre->next;

} }printf("最終活下來的人是第 %d 位\n", cur->data);

}

int main()

執行結果:

鍊錶實現約瑟夫環問題

約瑟夫環 約瑟夫問題 是乙個數學的應用問題 已知n個人 以編號1,2,3.n分別表示 圍坐在一張圓桌周圍。從1開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到圓桌剩下最後乙個人,求那個人的位置。總體思路 1 建立鍊錶 用尾插法建立 2 當人數大於...

鍊錶實現約瑟夫環

約瑟夫環 約瑟夫問題 是乙個數學的應用問題 已知n個人 以編號1,2,3.n分別表示 圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依 此規律重複下去,直到圓桌周圍的人全部出列。實現 include using namespace ...

用C鍊錶實現約瑟夫環問題

問題 設有n個人圍成乙個圓圈,現從第s個人開始報數,數到第m的人出列,然後從出列的下乙個人重新開始報數,數到第m的人再次出列,如此反覆,直到所有的人全部出列為止。對於任意給定的n s m,求按出列次序得到的n個人員的序列。例 就是問題簡單示例,裡面是每次要迴圈的資料,後面的s是出列的人 思路 先建立...