约瑟夫退圈问题

利用 循环链表类 实现约瑟夫退圈问题: n 个人 (不同 id )围成一个圈,从 startId( 任意数 ) 个开始报数 m( 任意数 ) 个 数,数 m 的人出列排成新队列, m 清零,然后又从下一个人开始数 m 个数开始,数到 m 就出列接在新队列尾部,如此重复,直到所有人都出列为止,请输出出列的次序 (依次输出出列人员的编号)

代码如下:

#include<iostream>
#include<iomanip>
#include<string>

using namespace std;

class CNode
{
public:
    int data;
    CNode * next;
    CNode() {}
    ~CNode() {}
};

class CLinkList
{
private:
    CNode* headNode ;    //头结点
    int m;  //报数人数
    int k;  //总人数
    int startId;  //开始报数人的ID
public:
    CLinkList() {}
    void BuildLinkList(); //链表的创建
    void DelNode( int a );      //删除结点
    void Joseph();      //实现约瑟夫退圈问题
    ~CLinkList(){}    //析构,释放内存
};

void CLinkList::BuildLinkList(  )
{
    headNode = new CNode;
    headNode->next = NULL;
    headNode->data = 1;
    CNode *p = headNode, *q;
    int i;
    for( i=2; i<=k; i++ )
    {
        q = new CNode;
        q->data = i;
        q->next = NULL;
        p->next = q;
        p = q;
    }
    p->next = headNode;     //最后一个结点连接头结点,实现链表循环
}

void CLinkList::Joseph()     //实现约瑟夫退圈问题
{
    cout<<"    约瑟夫退圈问题     "<<endl;
    cout<<"请输入总人数,报数人数:";
    cin>>k>>m;
    if( m>k )
    {
        m = m % k;
    }
    BuildLinkList();
    cout<<"请输入开始退圈人的ID:";
    cin>>startId;
    if( startId>k )
    {
        startId = startId % k;
    }
    CNode *p = headNode, *q;
    while( p->data != startId )
    {
        p = p->next;
    }
    p = p->next;
    cout<<"依次退圈的人:"<<endl;
    int i = 0;      //记录报数
    int s = 0;  //记录退圈人数
    while( s<k )
    {
        i++;
        q = p;
        p = p->next;
        if( i == m )
        {
            s++;
            cout<<q->data<<"号"<<endl;
            DelNode( q->data );
            i = 0;
        }
    }
}
void CLinkList::DelNode( int a )
{
    CNode *p = headNode, *q, *d;
    if( headNode->data == a )
    {
        while( p->next != headNode )
        {
            p = p->next;
        }
        d = headNode;
        headNode = headNode->next;
        p->next = headNode;
         delete d;
    }
    else
    {
        while( p->data != a )
        {
            q = p;
            p = p->next;
        }
       d = p;
        q->next = p->next;
        delete d;
    }
}

int main()
{
    CLinkList cli;
    cli.Joseph();
    return 0;
}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值