约瑟夫环的实现:设有n个人围坐在圆桌周围,现从某个位置 i 上的人开始报数,数到 m 的人就站出来。下一个人,即原来的第m+1个位置上的人,又从1开始报数,再是数到m的人站出来。依次重复下去,直到全部的人都站出来,按出列的先后又可得到一个新的序列。由于该问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus 问题。
例如:当n=8,m=4,i=1时,得到的新序列为:
4,8,5,2,1,3,7,6
顺序表
#include<iostream>
using namespace std;
void main()
{
int n, m, i;
cout<< "输入人数:";
cin>> n;
cout << "输入出列下标:";
cin >> m;
cout << "输入第几个开始:";
cin >> i;
i = i % n;
int* a = new int[n];
for (int k = 0; k < n; k++)//数组赋值
{
a[k] = k + 1;
}
int index = i + m - 2;//第一个下标
int num;
while (n > 1)
{
cout << a[index];//弹出要删的元素
num = index - 1;//记录要删除的下标的前一个下标
if (num == -1)
{
num = n - 2;//删除-1 数组自然-1
}
for (;index < n - 1;index++)//修改数组
{
a[index] = a[index + 1];
}
n--;
index = (num + m) % n;//新下标
}
cout << a[0] << endl;
}
单项循环链表
#include <iostream>
using namespace std;
typedef struct Node
{
int data;
struct Node* next;
}node;
int main()
{
node* L, * r, * s, * p;
L = new node;
r = L;
int n, m,k;
int j = 0;
cout << "输入总人数,第几个出局,从第几个开始数"<<endl;
cin >> n >> m >> k;
for (int i = 1;i <= n;i++)
{
s = new node;
s->data = i;
r->next = s;
r = s;
}
r->next = L->next;//尾指向第一个数
p = L->next;//p☞第一个数
delete L;//单向循环
for (int a=1;a < k;a++)//使p指针到第K个数
{
p = p->next;
}
while (p->next != p)
{
for (int i=1;i<m-1;i++)//
{
p = p->next;
}
cout << p->next->data;//输出第m个结点的值
p->next = p->next->next; //删除第m个结点
p = p->next;//指针指向m的下一个结点继续循环
}
cout << p->data;
return 0;
}