【问题描述】
约瑟夫环问题(Josephus)
用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。(约瑟夫环问题 Josephus)
【解题思路】
构建一个循环链表,每个结点的编号为1,2,......,n。每次从当前位置向前移动m-1步,然后删除这个结点。
【C程序代码】
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int num;
struct node *next;
}node;
node *create_list(int n)
{
int i;
node *head;
node *p_cur, *p_pre;
head = (node *)malloc(sizeof(node));
head->num = 1;
head->next = NULL;
p_pre = head;
for(i = 2; i <= n; i++)
{
p_cur = (node *)malloc(sizeof(node));
p_cur->num = i;
p_pre->next = p_cur;
p_pre = p_cur;
}
p_cur->next = head;
return head;
}
void print_list(node* head)
{
node *p;
printf("%d ", head->num);
p = head->next;
while(p != head)
{
printf("%d ", p->num);
p = p->next;
}
}
void josephus(node *head, int m)
{
node *p_cur, *p_pre;
int count;
count = 1;
p_cur = p_pre = head;
while(1)
{
if(count == m)
{
p_pre->next = p_cur->next;
printf("%d ", p_cur->num);
free(p_cur);
p_cur = p_pre->next;
count = 1;
}
p_pre = p_cur;
p_cur = p_cur->next;
if(p_pre == p_cur)
{
printf("%d ", p_pre->num);
free(p_pre);
break;
}
count++;
}
}
int main(void)
{
node *head;
head = create_list(5);
print_list(head);
printf("\n");
josephus(head, 2);
printf("\n");
return 0;
}