/**/
/************************************************************************
Josephus问题求解:
设有n个人围坐一个圆桌周围,,现从第S人开始报数,数到第m的人出列,
然后从出列的下一个重新开始报数,数列的第m个人又出列……如此重复,直
到所有的人全部出列为止。对任意给定的n、s、m,求按出列次序得到的n个
人员的顺序表。
Description:求解Josephus问题
Input: n----编号的最大值;
s----开始的编号;
m----计数值;
OutPut: 输出出队的顺序。
*************************************************************************/
void Josephus( int m, int n, int s)
... {
/**//* 构造循环单链表 */
Node *head = new Node(1);
head->next = head;
Node *h = head;
for (int i = 2; i <= n; i++)
...{
try
...{
h->next = new Node(i, head);
}
catch (bad_alloc &e)
...{
cout << e.what() << endl;
}
h = h->next;
}
/**//* 寻找开始编号的指针 */
for (Node *p = head; ; p = p->next )
...{
if (p->val == s)
...{
break;
}
}
h = p;
while (h != h->next)
...{
/**//* 计数,找到计数值所在指针的前一指针 */
for (int j = 0; j < m - 2; j++)
...{
h = h->next;
}
cout << h->next->val << endl;
/**//* 保存将删除的节点的指针 */
p = h->next;
/**//* 删除出队的节点 */
h = h->next = h->next->next;
delete p;
p = NULL;
}
/**//* 输出最后一个出队的值 */
cout << h->val << endl;
}
/**/ /* Josephus 问题的另一种解法(使用数组)*/
void Josephus1( int m, int n, int s)
... {
int *data = NULL;
try
...{
data = new int[n];
}
catch (bad_alloc &e)
...{
cout << e.what() << endl;
}
for (int i = 0; i < n; i++)
...{
data[i] = i + 1;
}
s--;
/**//* 数组长度递减 */
for (int j = n; j > 0; j--)
...{
for (int k = 0; k < m - 1; k++)
...{
s = ++s % j;
}
cout << data[s] << endl;
for (k = s; k < j - 1 ; k++)
...{
data[k] = data[k + 1];
}
}
delete []data;
}
/**/ /* Jesephus问题求解的递归算法 */
void JosephusRecur2( int m, int n, int s, int * data)
... {
if (1 == n)
...{
cout << data[0] << endl;
return;
}
s--;
for (int k = 0; k < m - 1; k++)
...{
s = ++s % n;
}
cout << data[s] << endl;
for (k = s; k < n - 1 ; k++)
...{
data[k] = data[k + 1];
}
/**//* 递归求剩下的长度为n-1的数组 */
JosephusRecur2(m, n - 1, s + 1, data);
}
Josephus问题求解:
设有n个人围坐一个圆桌周围,,现从第S人开始报数,数到第m的人出列,
然后从出列的下一个重新开始报数,数列的第m个人又出列……如此重复,直
到所有的人全部出列为止。对任意给定的n、s、m,求按出列次序得到的n个
人员的顺序表。
Description:求解Josephus问题
Input: n----编号的最大值;
s----开始的编号;
m----计数值;
OutPut: 输出出队的顺序。
*************************************************************************/
void Josephus( int m, int n, int s)
... {
/**//* 构造循环单链表 */
Node *head = new Node(1);
head->next = head;
Node *h = head;
for (int i = 2; i <= n; i++)
...{
try
...{
h->next = new Node(i, head);
}
catch (bad_alloc &e)
...{
cout << e.what() << endl;
}
h = h->next;
}
/**//* 寻找开始编号的指针 */
for (Node *p = head; ; p = p->next )
...{
if (p->val == s)
...{
break;
}
}
h = p;
while (h != h->next)
...{
/**//* 计数,找到计数值所在指针的前一指针 */
for (int j = 0; j < m - 2; j++)
...{
h = h->next;
}
cout << h->next->val << endl;
/**//* 保存将删除的节点的指针 */
p = h->next;
/**//* 删除出队的节点 */
h = h->next = h->next->next;
delete p;
p = NULL;
}
/**//* 输出最后一个出队的值 */
cout << h->val << endl;
}
/**/ /* Josephus 问题的另一种解法(使用数组)*/
void Josephus1( int m, int n, int s)
... {
int *data = NULL;
try
...{
data = new int[n];
}
catch (bad_alloc &e)
...{
cout << e.what() << endl;
}
for (int i = 0; i < n; i++)
...{
data[i] = i + 1;
}
s--;
/**//* 数组长度递减 */
for (int j = n; j > 0; j--)
...{
for (int k = 0; k < m - 1; k++)
...{
s = ++s % j;
}
cout << data[s] << endl;
for (k = s; k < j - 1 ; k++)
...{
data[k] = data[k + 1];
}
}
delete []data;
}
/**/ /* Jesephus问题求解的递归算法 */
void JosephusRecur2( int m, int n, int s, int * data)
... {
if (1 == n)
...{
cout << data[0] << endl;
return;
}
s--;
for (int k = 0; k < m - 1; k++)
...{
s = ++s % n;
}
cout << data[s] << endl;
for (k = s; k < n - 1 ; k++)
...{
data[k] = data[k + 1];
}
/**//* 递归求剩下的长度为n-1的数组 */
JosephusRecur2(m, n - 1, s + 1, data);
}
int
main()
... {
/**//* test nonRecursive Jesephus solution */
cout << "Josephus:" << endl;
Josephus(4, 7, 1);
cout << "Josephus1:" << endl;
Josephus1(4, 7, 1);
/**//* test recursive Jesephus solution */
int *data = new int[7];
for (int i = 0; i < 7; i++)
...{
data[i] = i + 1;
}
cout << "Josephus2:" << endl;
JosephusRecur2(4, 7, 1, data);
delete []data;
return 0;
}
... {
/**//* test nonRecursive Jesephus solution */
cout << "Josephus:" << endl;
Josephus(4, 7, 1);
cout << "Josephus1:" << endl;
Josephus1(4, 7, 1);
/**//* test recursive Jesephus solution */
int *data = new int[7];
for (int i = 0; i < 7; i++)
...{
data[i] = i + 1;
}
cout << "Josephus2:" << endl;
JosephusRecur2(4, 7, 1, data);
delete []data;
return 0;
}