已知 n 个人(以编号1, 2, 3 ,4, 5 ,6 ... .. .n)围坐一张圆桌周围。从编号为k 的人开始报数,数到m 的那个人出列;他的下一个人又从 1开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列。请用C++编程。
整个程序分为3个步骤:
第一步:建立一个有n个元素的循环链表,链表是从1的编号开始的。
第二步:是从链表的表头数到第 k -1个值。
第三步:从 k-1 开始数到m 个值,删除该值,继续开始数,继续删。。。。。。。,直到删除完。
#include <iostream>
using namespace std;
#define ERROR 0
typedef struct LNode
{
int data;
struct LNode *link;
LNode()
{
data = 0;
link = NULL;
}
}LNode,*LinkList;
/************************************************************************/
/* n 为总人数 */
/* k 为第一个开始报数的人 */
/* m为出列者喊到的数 */
/************************************************************************/
void Josephus(int n,int k,int m)
{
int count=2*n;
if(n<0||k<0||m<0) return;
LinkList phead,prenode,curr,cur;
phead = new LNode();
phead->data = 1;
phead->link = NULL; //建立一个循环链表
curr = phead;
for (int i=2;i<=n;i++)
{
LinkList temp = new LNode();
temp->data = i;
temp->link = NULL;
curr->link = temp;
curr = temp;
}
curr->link = phead;
k=k-1;
while(k--)
{
curr = curr->link;
}
while(n--)
{
for (int s=m-1;s>0;curr =curr ->link,--s);
cur=curr->link;
curr->link = cur->link;
printf("%d ",cur->data);
free(cur); //释放空间。
}
}
void main()
{
Josephus(6,1,5);
system("pause");
}