- /*
- Name: 约瑟夫环 模拟
- Author: 李帅
- Date: 10-11-08 23:53
- Description:
- 本程序模拟约瑟夫问题,自己写时参考了网上一些资料,我在此作了详细的注释。
- 约瑟夫问题: 一群人围成一圈,这群人共有 n个人,每个人身上都一个value,依次给这圈人编号:
- 1,2,n 一开始报数的上限值为m从第一个人(编号:1)自一开始报数报到m时停止报数,报到m的人出列,
- 将他的密码做为新的m值,从他的顺时针方向开始的下个人开始从新从一报数,如此下去,直至所有的人出列为止。
- 这里输出出列顺序
- */
- #include <iostream>
- using namespace std;
- //定义节点结构
- typedef struct Node
- {
- int value;
- int num;
- Node *next;
- }Node;
- //定义总人数
- int n;
- //开始位置指针
- Node *FirstNode = NULL;
- //创建第一个循环链表,先创建一个,后面有用
- void CreateFirst(int);
- //删除节点p后面的节点
- void DeleteNode(Node*);
- int main()
- {
- //==========创建循环链表=============
- //读入总人数
- cout << "总人数 n=";
- cin >> n;
- //用来读入人的value值
- int TempValue;
- //读入第一个人的value,用于 InitList
- cout << "num=1 value=";
- cin >> TempValue;
- //创建第一个循环链表,因为每次创建新节点都要和第一个节点相连,所以先创建第一个
- CreateFirst(TempValue);
int i;
- //定义临时变量,ToBeAdded用来创建新节点,current指向当前最后一个节点
- Node *ToBeAdded,*current = FirstNode;
- for( i=2;i<=n;i++ )
- {
- ToBeAdded = new Node();
- cout << "num=" << i << " value=";
- cin >> TempValue;
- ToBeAdded->value = TempValue;
- ToBeAdded->next = FirstNode; //构成循环链表
- current->next = ToBeAdded; //连接新节点
- ToBeAdded->num = i;
- current = ToBeAdded; //current移到最新位置
- }
- Node *p = FirstNode;
- //========链表创建结束===========================
- //==========开始模拟运行=====================
- current = FirstNode;
- Node *tem = current->next;
- Node *previous = tem;
- //把previous 放在tem前面
- while(tem!=current)
- {
- previous = tem;
- tem = tem->next;
- }
- int m;
- cout << "输入给定的m值:";
- cin >> m;
- i = 1;
- int count = n;
- //模拟整个过程
- while(i <= m)
- {
- if(count==0)
- {
- cout << "所有人都已出列" << endl;
- break;
- }
- if(i==m)//已循环m次,即数过m个人后
- {
- m = current->value;
- i = 0; //重新对m赋予新的值,并对i初始化为0,后面加1,还是从1开始
- cout << current->num << endl; //输出删除节点number
- DeleteNode(previous); //注意,删除的是当前节点current
- count--;
- current = previous; //这里是为了防止后面previous = current;,而改变当前值
- }
- i++;
- previous = current;
- current = current->next;
- }
- system("pause");
- return 0;
- }
- void CreateFirst(int va)
- {
- FirstNode = new Node();
- FirstNode->num = 1;
- FirstNode->value = va;
- FirstNode->next = FirstNode;
- }
- //删除节点p后面的节点,之所以不删除当前节点,是因为如果删除当前节点,就不方便将当前节点前后节点连接起来
- void DeleteNode(Node *p)
- {
- Node *tmp = p->next;
- p->next = tmp->next;
- delete tmp;
- }