约瑟夫退圈问题

3. 约瑟夫退圈问题 :利用 循环链表类 实现约瑟夫退圈问题: n 个人
(不同 id )围成一个圈,从 startId( 任意数 ) 个开始报数 m( 任意数 )
数,数 m 的人出列排成新队列, m 清零,然后又从下一个人开始数
m 个数开始,数到 m 就出列接在新队列尾部,如此重复,直到所有
人都出列为止, 请输出出列的次序 (依次输出出列人员的编号)。
说明:参数 n stratId m 要通过输入确定,注意要考虑 startId m
大于 n 的情况
代码示例:
#include<iostream>
using namespace std;

//节点类
class Node
{
public:
    int id;
    Node * next;

    Node (int i):id(i),next(nullptr){}
};

//链表类
class List
{
public:
    Node * head;
    Node * endnode;
    List ():head(nullptr){}

    void add(int i)//为链表添加一个节点
    {
        Node * nownode=new Node(i);
        if(head==nullptr)
        {
            head=nownode;
        }
        else
        {
            Node * current=head;
            while(current->next)
            {
                current=current->next;
            }
            current->next=nownode;
            endnode=nownode;
        }
    }
    void printlist()//输出链表
    {
        Node * current=head;
        while(current)
            cout<<current->id<<" ";
        cout<<endl;
    }
};

void display(int n,int start,int m)
{
    //先创建一个循环链表,记录下每个人的id
    List list1;
    cout<<"输入从第一个人到最后一个人的id:";
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        list1.add(x);
    }
    list1.endnode->next=list1.head;//尾结点的指针指向头结点,形成一个循环
    //开始循环报数
    //List list2;//报到m的人重新站成一个新的队列
    Node * current=list1.endnode;
    while(1)
    {
        Node * temp=current->next;
        if(temp->id==start) break;
        current=current->next;
    }
    //temp指向了start
    int count=0;
    while(current->next!=current)//如果current为空,说明全部退圈
    {
        Node * temp=current->next;
        ++count;
        if(count==m)
        {
            cout<<temp->id<<" ";
            current->next=temp->next;
            delete temp;
            count=0;
        }
       else  current=current->next;
    }
    cout<<current->id<<endl;

}

int main()
{
    int n,start,m;
    cout<<"请输入人数:";
    cin>>n;
    cout<<"从第几个人开始报数(id):";
    cin>>start;
    cout<<"报数到几时退出循环:";
    cin>>m;
    display(n,start,m);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值