1.問題描述
約瑟夫環(約瑟夫問題)是乙個數學的應用問題:已知n個人(以編號1,2,3…n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下乙個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。
鍊錶思路:
我是通過單鏈表實現的,
首先要思考怎麼成乙個圈?(迴圈鍊錶不必考慮這個問題。)
1.給n個人依次從小到大編號,先將最大號碼放入鍊錶,再定義乙個指標plast代表表尾,此時它既為表頭phead,又為表尾。
2.依次將後面的號碼放入鍊錶,表頭phead不斷更新,表尾plast始終指向最開始放入的最大號碼。
3.待號碼全部放入時,將表尾的next指向表頭,成環。
//先把最大的數放進去
slistpushfront(&phead, m);
plast = phead;
//依次放入剩下的數,形成鍊錶
for (i = m - 1; i >=1; i--)
plast->next = phead;//形成乙個環
然後再思考怎樣數數?1.首先先找到數數的結束條件,就是只剩下乙個人時,停止數數,玩家勝利。數數的次數應該=剩下的人數-1。每當有乙個人出局時,數數次數就減少一次。
2.再找乙個指標,它指向的節點的next就是要出局的節點。
cur = plast;//只有第乙個跳的個數不一樣,這樣可以保證第一次的正確
for (; m > 1; m--)
printf("%d號出圈\n", cur->next->data, i);
slisteraseafter(cur);
}
測試輸入人數m為5,數的數字n為2:
源**:
#include
#include
#include
#include
//無頭單向非迴圈鍊錶
typedef
int sltdatatype;
typedef
struct slistnode
slistnode;
void
slistinit
(slistnode *
*pphead)
//初始化
void
slistpushfront
(slistnode *
*pphead, sltdatatype x)
//頭插
void
slisteraseafter
(slistnode *pos)
//刪除pos後面的節點,把pos的位址傳進來,改變pos指向的空間
pos->next = tmp->next;
tmp =
null;}
intmain()
plast->next = phead;
//形成乙個環
cur = plast;
//只有第乙個跳的個數不一樣,這樣可以保證第一次的正確
for(
; m >
1; m--
)printf
("%d號出圈\n"
, cur->next->data, i)
;slisteraseafter
(cur);}
printf
("%d號勝利\n"
, cur->data)
;free
(cur)
;system
("pause");
return0;
}
資料結構 約瑟夫環問題
實驗一線性表的應用 實驗目的和要求 通過實驗進一步理解線性表的邏輯結構和儲存結構,提高使用理論知識指導解決實際問題的能力,熟練掌握鍊錶的實際應用。主要內容 題目1 josephus環問題 問題描述 約瑟夫 joseph 問題的一種描述是 編號為1,2,n的n個人按順時針方向圍坐一圈,每人持有乙個密碼...
資料結構 約瑟夫環問題
約瑟夫問題是個有名的問題 n個人圍成一圈,從第乙個開始報數,第m個將被殺掉,最後剩下乙個,其餘人都將被殺掉。例如n 6,m 5,被殺掉的順序是 5,4,6,2,3。分析 1 由於對於每個人只有死和活兩種狀態,因此可以用布林型陣列標記每個人的狀態,可用true表示死,false表示活。2 開始時每個人...
資料結構之約瑟夫環問題
有 n 個人,按 1 到 n 編號,要求從第 s 個人開始迴圈報數,報到 m 時,此人出列,再從下乙個人開始報 m個數,直到所有人出列。給出 n 個人出列的順序。include stdio.h typedef struct nodelnode,linklist void creatjoseph li...