欢迎来到 A_Dull_Rabbit 的博客

数据结构实训(二)--- 约瑟夫环

约瑟夫(Flavius Josephu)是公元1世纪的一位著名历史学家。约瑟夫环(也称为约瑟夫问题)是一个数学的应用问题,可以简单地表述如下:
已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列,他的下一个人又从1开始报数,数到m的那个人又出列,依此规律重复下去,直到圆桌周围只剩下一个人为止。
【输入形式】参与游戏的总人数,退出游戏的数字以及游戏开始的数字。
【输出形式】游戏最后剩余的编号。
【样例输入】
15 4 2
【样例输出】
14
【说明】考虑到该问题模型是个环,所以可以用循环队列解决。考虑到频繁地插入和删除操作,所以用队列的链式存储结构,即循环单链表。为了统一对表中任意结点的操作,循环单链表可以不带头结点,当然也可以带有头结点。

#include<iostream>
using namespace std;

struct node
{
    int data;
    node* next;
};

class cirLinkList
{
public:
    cirLinkList(int length)
    {
        rear = new node;  // 尾指针
        rear->data = 1;
        rear->next = rear;

        for(int i=2; i<=length; i++)    // 循环链表构建
        {
            node* p = new node;
            p->data = i;
            p->next = rear->next;
            rear->next = p;
            rear = p;
        }
    };

    int Joseph(int out, int beg)
    {
        node* pre = rear, *s = NULL; // 起始位置
        beg = beg-1;
        while(beg--)    // 找到游戏起始位置
        {
            pre = pre->next;
        }
        s = pre->next;
        int countOut = 1;
        while(s->next!=s)
        {
            if(countOut < out)
            {
                pre = s;
                s = s->next;
                countOut++;
            }
            else {
                pre->next = s->next;
                delete s;
                s = pre->next;
                countOut=1;
            }
        }
        return s->data;
    }
private:
    node* rear;
};

int main()
{
    int n, k, m;
    cin >> n >> k >> m;

    cirLinkList a(n);
    cout << a.Joseph(k, m);
}

 

posted on 2020-03-24 14:32  A_Dull_Rabbit  阅读(315)  评论(0编辑  收藏  举报

导航