/********************************************************************
created: 2007/03/31
created: 31:3:2007 17:50
filename: E:/PRACTICE/Josephus/main.cpp
file path: E:/PRACTICE/Josephus
file base: main
file ext: cpp
author: 云中哈哈
purpose: 约瑟夫环问题 Josephus
原题:
用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。
下面是解决方案:
*********************************************************************/
#include <iostream>
#include <malloc.h>
//结构体和函数声明
typedef struct nNode {
int num;
struct nNode *next;
}node;
//函数声明
node *node_create(int n);
/*
* 说明:初始化链函数
* 参数:
* n (in)表示初始化多少人的一个循环链
*/
//函数实现
node *node_create(int n)
{
node *pHead=NULL; //要返回的头指针
if (0!=n) {
node *piter=NULL; //
//分配内存
piter=(node *)malloc(n * sizeof(node));
if (piter==NULL) {
return NULL;
}
else{
//内存初始化
memset(piter, 0 ,n * sizeof(node));
}
pHead=piter;
for (int i=1;i<n;++i) {//要从1开始数,所以第一个人的号码是1
piter->num=i;
piter->next=piter+1;
piter=piter->next;//指向下一个节点
}
//最后一个结点要指向链首,形成循环链
piter->num=n;
piter->next=piter;
}
return pHead;//返回头指针、函数结束
}
void main()
{
int n,m;
n=20; //20个人
m=6; //数到6的人离开
node *p_list, *p_iter;
//构造20人
p_list = node_create(n); //返回链头
p_iter=p_list; //迭代器
//遍历链中元素
for (int i=0;i<20;i++) {
printf("%d/n",(p_iter+i)->num);
}
m%=n; //表示数到第M时是第几个人,他应该走
while (p_iter != p_iter->next) {//不是最后一个人时
//每次都从1数到第M-1个结点
for (int i=1;i<m-1;i++) {
p_iter=p_iter->next;
}
//输出走的人
printf("%d/n",p_iter->next->num);
//删除此人
p_iter->next=p_iter->next->next;
//把下一个做第一人,继续从1数数
p_iter=p_iter->next;
}
//只剩下一个人,输出他
printf("%d/n is the last one",p_iter->num);
//释放内存资源
free(p_list);
}