迴圈鍊錶的應用 約瑟夫問題

2021-10-09 13:08:56 字數 1881 閱讀 7209

約瑟夫問題是個有名的問題: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...