// 循环链表.cpp : 定义控制台应用程序的入口点。
//约瑟夫问题的解答
/*
约瑟夫问题的原理:
编号为1~N的N个人按顺时针方向围坐一圈,每人持有
一个密码(正整数),开始任选一个正整数作为报数上限值M,
从第1个人按顺时针方向自1开始报数,报到M时停止。报M
的人出列,将他的密码作为新的M值,
从它顺时针方向上的下一个人开始从1报数,
如此下去,直至所有人全部出列为止,
试设计一个程序求出出列顺序
*/
//对于所有人围成的圆圈所对应的数据结构采用不带头节点的循环单链表描述
#include "stdafx.h"
#include <iostream>
using namespace std;
typedef struct node {
int data;//节点内容
node *next;//下一个节点
}node;
node * create(int n){//构造节点数量为n的单向循环链表
node *pRet=NULL;
if (0!=n){
int n_idx=1;
node *p_node=NULL;
//构造n个node
p_node=new node[n];
if (NULL==p_node) //内存申请失败,返回NULL
{
return NULL;
}
else{
memset(p_node,0,n*sizeof(node));//初始化内存
}
pRet=p_node;
while (n_idx<n){ //构造循环链表
//初始化链表的每个节点从1到n
p_node->data=n_idx;
p_node->next=p_node+1;
p_node=p_node->next;
n_idx++;
}
p_node->data=n;
p_node->next=pRet;
}
return pRet;
}
int _tmain(int argc, _TCHAR* argv[])
{
node *pList=NULL;
node *pIter=NULL;
int n=5;
int m=2;
//构造单向循环链表
pList=create(n);
//约瑟夫循环取数
pIter=pList;
m%=n;
cout<<"开始时的报数上限值M:"<<m<<endl;
while (pIter!=pIter->next){
int i=1;
//取到第m-1个节点
for (;i<m-1;i++){
pIter=pIter->next;
}
//输出第m个节点的值
cout<<pIter->next->data<<" ";
//从链表中删除第m个节点
pIter->next=pIter->next->next;
pIter=pIter->next;
}
cout<<"\n==========最后出局的人=========\n";
cout<<pIter->data<<" ";
//释放申请的空间
system("pause");
delete [] pList;
return 0;
}