已知 n 個人(以編號1, 2, 3 ,4, 5 ,6 ... .. .n)圍坐一張圓桌周圍。從編號爲k 的人開始報數,數到m 的那個人出列;他的下一個人又從 1開始報數,數到m的那個人又出列;依次規律重複下去,直到圓桌周圍的人全部出列。請用C++編程。
整個程序分爲3個步驟:
第一步:建立一個有n個元素的循環鏈表,鏈表是從1的編號開始的。
第二步:是從鏈表的表頭數到第 k 個值。
第三步:從 k 的後面開始輸入 m 個值,刪除該值,繼續開始數,繼續刪。。。。。。。,直到刪除完。
- #include <iostream>
- using namespace std;
- #define ERROR 0
- typedef struct LNode
- {
- int data;
- struct LNode *link;
- LNode()
- {
- data = 0;
- link = NULL;
- }
- }LNode,*LinkList;
- /************************************************************************/
- /* n 爲總人數 */
- /* k 爲第一個開始報數的人 */
- /* m爲出列者喊到的數 */
- /************************************************************************/
- void Josephus(int n,int k,int m)
- {
- //pnode 爲當前節點,secondnode爲輔助節點,指向pnode的前驅節點,list爲頭結點
- if(n<0||k<0||m<0) return;
- LinkList pnode,prenode,curr;
- pnode = new LNode();
- pnode->data = 1;
- pnode->link = pnode; //建立一個循環鏈表
- curr = pnode;
- for (int i=2;i<=n;i++)
- {
- LinkList temp = new LNode();
- temp->data = i;
- temp->link = curr->link;
- curr->link = temp;
- curr = temp;
- }
- prenode = curr;
- while(k--)
- {
- prenode = pnode; //prenode是pnode的前一個結點。
- pnode = pnode->link; //移動結點 pnode是第k個元素
- }
- while(n--)
- {
- //for 是移動m個位置pnode是移動到的m位置,prenode是pnode的前一個結點
- for (int s=m;--s;prenode = pnode,pnode = pnode->link);
- prenode->link = pnode->link; //刪除pnode結點
- printf("%d ",pnode->data); //打印刪除的結點
- free(pnode); //釋放空間
- pnode = prenode->link; //從prenode的下一個結點開始,數一個m個結點的值。
- }
- }
- void main()
- {
- Josephus(5,3,1);
- system("pause");
- }
運行的結果: