问题引入:
据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39
个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
问题解决:
用循环链表模拟约瑟夫问题,把41个人自杀的顺序编号输出。
#include"pch.h"
#include <stdio.h>
#include <stdlib.h>
//声明结点
typedef struct node
{
char data;
struct node* next;
}node;
//建立循环链表
node *Create(int n);
int main()
{
int n = 41;
int l=3;
int i;
node *p = Create(n); //p是一个指向头结点的指针
node *temp;
l %= n; //l==2
while (p != p->next) //非空表
{
for (i = 1; i < l - 1; i++)
p = p->next;
printf("%d ", p->next->data);
temp = p->next; //删除第m个结点
p->next = temp->next;
free(temp);
p = p->next;
}
printf("%d\n", p->data);
return 0;
}
node *Create(int n)
{
node *head, *p = NULL; //p为索引指针
head = (node*)malloc(sizeof(node));
node *s; //临时结点
int i = 1;
p = head;
if (n != 0)
{
while (i <= n)
{
s= (node*)malloc(sizeof(node));
s->data = i++; //为循环链表初始化,第一个结点为1,第二个结点为2……
p->next = s;
p = s;
}
p->next = head->next; //终端结点指向开始结点
}
free(head);
return p->next; //返回头结点
}