Josephus问题求解

/************************************************************************
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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值