約瑟夫問題的示意圖
josephu 問題
josephu 問題為:設編號為 1,2,… n 的 n 個人圍坐一圈,約定編號為 k(1<=k<=n)的人從 1 開始報數,數到 m 的那個人出列,它的下一位又從 1 開始報數,數到 m 的那個人又出列,依次類推,直到所有人出列為止,由此 產生乙個出隊編號的序列。
提示
用乙個不帶頭結點的迴圈鍊錶來處理 josephu 問題:先構成乙個有 n 個結點的單迴圈鍊錶,然後由 k 結點起從 1 開 始計數,計到 m 時,對應結點從鍊錶中刪除,然後再從被刪除結點的下乙個結點又從 1 開始計數,直到最後乙個結點從鍊錶中刪除演算法結束。
約瑟夫問題-建立環形鍊錶的思路**
約瑟夫問題-小孩出圈的思路分析圖
}// 建立乙個環形的單向鍊錶
class
circlesinglelinkedlist
boy curboy = null;
// 輔助指標,幫助構建環形鍊錶
// 使用for來建立我們的環形鍊錶
for(
int i =
1; i <= nums; i++
)else}}
// 遍歷當前的環形鍊錶
public
void
showboy()
// 因為first不能動,因此我們仍然使用乙個輔助指標完成遍歷
boy curboy = first;
while
(true
) curboy = curboy.
getnext()
;// curboy後移}}
// 根據使用者的輸入,計算出小孩出圈的順序
/** *
* @param startno
* 表示從第幾個小孩開始數數
* @param countnum
* 表示數幾下
* @param nums
* 表示最初有多少小孩在圈中
*/public
void
countboy
(int startno,
int countnum,
int nums)
// 建立要給輔助指標,幫助完成小孩出圈
boy helper = first;
// 需求建立乙個輔助指標(變數) helper , 事先應該指向環形鍊錶的最後這個節點
while
(true
) helper = helper.
getnext()
;}//小孩報數前,先讓 first 和 helper 移動 k - 1次
for(
int j =
0; j < startno -
1; j++
)//當小孩報數時,讓first 和 helper 指標同時 的移動 m - 1 次, 然後出圈
//這裡是乙個迴圈操作,知道圈中只有乙個節點
while
(true
)//讓 first 和 helper 指標同時 的移動 countnum - 1
for(
int j =
0; j < countnum -
1; j++
)//這時first指向的節點,就是要出圈的小孩節點
system.out.
printf
("小孩%d出圈\n"
, first.
getno()
);//這時將first指向的小孩節點出圈
first = first.
getnext()
; helper.
setnext
(first);//
} system.out.
printf
("最後留在圈中的小孩編號%d \n"
, first.
getno()
);}}
// 建立乙個boy類,表示乙個節點
class
boypublic
intgetno()
public
void
setno
(int no)
public boy getnext()
public
void
setnext
(boy next)
}
單向環形鍊錶(約瑟夫問題)
josephu 問題 josephu問題為 設編號為1,2,n的n個人圍坐一圈,約定編號為k 1 k n 的人 從1開始報數,數到m的那個人出列,它的下一位又從1開始報數,數到m的那個人又出列,依次類推,直到所有人出列為止,由此產生 乙個出隊編號的序列。提示用乙個不帶頭結點的迴圈鍊錶來處理josep...
單向環形鍊錶 約瑟夫問題
如圖,鍊錶的最後乙個節點的next指向鍊錶的第乙個節點,形成乙個環形鍊錶。josephu 約瑟夫 約瑟夫環 問題 設編號為1,2,3 n的 n個人坐成一圈,編號為k 1 k n 的人從1開始報數,數到m的那個人出列,他的下一位繼續從1開始報數,數到m的那個人又出列,依次類推,直到所有人出列為止,由此...
單向環形鍊錶 約瑟夫問題
單向環形鍊錶 約瑟夫問題 單向環形鍊錶 joseph 約瑟夫 約瑟夫環 問題 joseph 問題為 設編號為1,2,n 的n 個人圍坐一圈,約定編號為k 1 k n 的人從1 開始報數,數到m 的那個人出列,它的下一位又從1 開始報數,數到m 的那個人又出列,依次類推,直到所有人出列為止,由此產生乙...