約瑟夫問題是個有名的問題:n個人圍成一圈,從第乙個開始報數,第m個將被殺掉,最後剩下乙個,其餘人都將被殺掉。例如n=6,m=5,被殺掉的順序是:5,4,6,2,3。由於需要不斷迴圈計數來確定被殺的人,所以使用迴圈鍊錶可以很好地解決這個問題。
迴圈鍊錶本質上就是將單鏈表中的尾結點指向頭結點,形成乙個環,所以建立的方式和單鏈表很相似。
void
initlist
(linklist *l,
int n)
//尾插法整表建立
r->next =
(*l)
;//鍊錶尾指向頭結點 形成迴圈鍊錶
}
建立好鍊錶後,需要先將工作指標移動至指定的位置k,接下來將從k位置開始計數。假設數到n的人將被殺死,那麼從k開始,往後移動n-1個位置,位置為n+k-1的人將被殺死,此時計數重新從n+k位置的人開始,如迴圈往復,當只剩最後乙個人的時候遊戲結束。所以迴圈結束的判斷標誌為p->next == p,當p結點的下乙個結點是它本身時,迴圈結束。
//約瑟夫環 從第k個人開始遊戲 以n為乙個迴圈
void
josephcircle
(linklist* l,
int k,
int n)
while
(p->next != p)
//當p的下乙個結點為它本身時 遊戲結束
q = p->next;
p->next = q->next;
p = p->next;
//移至下乙個節點 此時計數重新變為1
printf
("出列人的編號為:%d\n"
, q->data)
;free
(q);
//刪除結點
}printf
("勝出者的編號為:%d"
, p->data)
;}
效果如圖所示:
附上完整**:
#include
#include
"malloc.h"
typedef
struct node
node;
typedef
struct node* linklist;
//尾插法生成迴圈鍊錶
void
initlist
(linklist *l,
int n)
r->next =
(*l)
;//鍊錶尾指向頭結點 形成迴圈鍊錶
}//約瑟夫環 從第k個人開始遊戲 以n為乙個迴圈
void
josephcircle
(linklist* l,
int k,
int n)
while
(p->next != p)
//當p的下乙個結點為它本身時 遊戲結束
q = p->next;
p->next = q->next;
p = p->next;
//移至下乙個節點 此時計數重新變為1
printf
("出列人的編號為:%d\n"
, q->data)
;free
(q);
//刪除結點
}printf
("勝出者的編號為:%d"
, p->data);}
intmain()
迴圈鍊錶 約瑟夫問題
設編號分別為 1,2,n的n個人圍坐一圈。約定序號為k 1 k n 的人從1開始計數,數到m的那個人出列,他的下一位又從1開始計數,數到m的那個人又出列,依次類推,直到所有人出列為止。演算法思路 1 先建立乙個有n個結點的單迴圈鍊錶,編號從1到n,代表n個人。2 找到第k個結點,即第乙個開始報數的人...
(迴圈鍊錶)約瑟夫問題
time limit 1000 ms memory limit 65536 kib submit statistic n個人想玩殘酷的死亡遊戲,遊戲規則如下 n個人進行編號,分別從1到n,排成乙個圈,順時針從1開始數到m,數到m的人被殺,剩下的人繼續遊戲,活到最後的乙個人是勝利者。請輸出最後乙個人的...
迴圈鍊錶 約瑟夫問題
n個人想玩殘酷的死亡遊戲,遊戲規則如下 n個人進行編號,分別從1到n,排成乙個圈,順時針從1開始數到m,數到m的人被殺,剩下的人繼續遊戲,活到最後的乙個人是勝利者。請輸出最後乙個人的編號。input 輸入n和m值。output 輸出勝利者的編號。struct st cr int n 建立迴圈鍊錶 t...