问题描述:
约瑟夫环问题(Josephus)
输出结果:
约瑟夫环问题(Josephus)
用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。(约瑟夫环问题 Josephus)
解法思路:
建立一个有N个元素的循环链表,然后从链表头开始遍历并记数,如果计数i==m(i初始为1)踢出元素,继续循环,当当前元素与下一元素相同时退出循环。
代码:
#include <iostream>
using namespace std;
typedef int Item;
typedef struct node * plist;
typedef struct node {
Item key;
node * next;
} node;
plist CreateList(int N){
/* plist head,curr,tail;*/
plist head,curr,tail;
int i;
head = NULL;
for(i=1;i<=N;i++){
curr = (plist)malloc(sizeof(node));
curr->key = i;
curr->next = NULL;
if(!head){
head = curr;
tail = curr;
} else{
tail->next = curr;
tail = tail->next;
}
}
tail->next = head;
return head;
};
void DisplayList(plist lst){
plist curr = lst;
do{
printf("%d\t",curr->key);
curr = curr->next;
}while(curr!=lst);
}
void DestroyList(plist lst){
plist curr = lst;
if(!lst)
return;
plist nxt;
do{
nxt = curr->next;
free(curr);
curr = nxt;
}while(curr!=lst);
}
void Josephus(plist lst,int M){
if(!lst)
return;
plist curr,pre;
int i = 1;
curr = lst;
pre = lst;
while(curr){
if(i==M){
printf("%d\t",curr->key);
pre->next = curr->next;
free(curr);
curr = pre->next;
i = 1;
}
pre = curr;
curr = pre->next;
if(pre == curr){
printf("%d\n",curr->key);
free(curr);
break;
}
i++;
}
}
void main()
{
plist lst = CreateList(7);
DisplayList(lst);
printf("\nJosephus:\n");
//DestroyList(lst);
Josephus(lst,2);
}
输出结果:
1 2 3 4 5 6 7
Josephus:
2 4 6 1 5 3 7