Josephus问题求解

来源:互联网 发布:网络自动打电话 编辑:程序博客网 时间:2024/05/22 07:41
/************************************************************************
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 
*= 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 *= 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 
= ++% 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 
= ++% 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(
471);
    cout 
<< "Josephus1:" << endl;
    Josephus1(
471);
    
/* test recursive Jesephus solution */
    
int *data = new int[7];
    
for (int i = 0; i < 7; i++)
    
{
        data[i] 
= i + 1;
    }

    cout 
<< "Josephus2:" << endl;
    JosephusRecur2(
471, data);
    delete []data;

    
return 0;
}
原创粉丝点击