约瑟夫环问题的C++算法,求用链表和递归两种方法,尽量详细!

用链表和递归两种方法解决这个问题,本人刚学数据结构,感觉无从下手,答案最好加以注释!!!不要随便写个答案!本人要的是理解这个问题的算法!详细会加分!... 用链表和递归两种方法解决这个问题,本人刚学数据结构,感觉无从下手,答案最好加以注释!!!不要随便写个答案!本人要的是理解这个问题的算法!详细会加分! 展开
 我来答
laughlee7468
推荐于2016-10-14 · TA获得超过2004个赞
知道小有建树答主
回答量:541
采纳率:100%
帮助的人:677万
展开全部

#include <iostream.h>
typedef struct node {  //结点类型定义,每个结点表示一个孩子
    int data;   //用于存放结点(孩子)编号
    node *next;
    node(int _data = 0, node *_next = NULL)  //带缺省参数的结点构造函数

        : data(_data),next(_next)

    {}
}*PNode, Node, *JosephusCycle;

void InitJCycle(JosephusCycle &last, int n) {

//初始化一个含有n个孩子的约瑟夫环,用带尾指针last的单循环链表表示,建表时采用首插法。
    last = new Node(n);  //last指针始终指向表尾结点,先创建表尾结点
    last->next = last;  //先初始化只含一个结点的环。
    for(int i = n - 1; i > 0; i--)
        last->next = new Node(i, last->next); //将新结点插入到表头(即循环链表表尾的下一个)之前
}

int GetWinner(JosephusCycle &last, int k) { //第一种方法,返回剩下的最后这个孩子的编号
    if(last == NULL) return -1;  //如果为空环,则返回-1表示失败
    int sum; //报数器
    PNode prior = last, current = prior->next;//current表示当前报数结点,prior为当前结点的前驱
    while(prior != current) {//如果prior==current则意味着环中剩下一个孩子
        sum = 1; //报数开始
        while(sum < k) {  //进行报数,报数时,current指针与prior指针需同时移动
            prior = current;
            current = prior->next;
            sum++;
        }
        cout << current->data << "\t"; //将报到k的孩子的序号输出。接下来的两行是该孩子删除出环
        prior->next = current->next;
        delete current;
        current = prior->next; //重新定位当前孩子
    }  //end while,结束循环时,环中只剩最后一个孩子
    last = current;  //将环尾指针指向最后这个孩子
    return last->data;
}

int GetWinner(JosephusCycle &last, int n, int k) {

//方法二,递归,参数last是环尾指针,n表示环中孩子个数,k为报数的目标数
    if(n == 1) return last->data;  //如果环中只有一个孩子,则结束,并返回这个孩子的编号
    int sum = 1; //否则,则开始报数
    while(sum < k) {  //进行报数
        last = last->next;
        sum++;
    }  //结束while时,last->next即为报到k的孩子结点
    PNode p = last->next;//本行及后续3行是输出该孩子并删除该孩子
    cout << p->data << "\t";
    last->next = p->next;
    delete p;
    GetWinner(last, n - 1, k); //在剩下的n-1个孩子的环中继续找优胜者
}

void main( ) {
    JosephusCycle cycle;
    int m, k, winner;
    cin >> m >> k;

    cout << "方法一的出圈序列为:\n";
    InitJCycle(cycle, m);
    winner = GetWinner(cycle, k);
    cout << "\n优胜者:" << winner << endl;

    delete cycle;

    cout << "\n方法二的出圈序列为:\n";
    InitJCycle(cycle, m);
    winner = GetWinner(cycle, m, k);
    cout << "\n优胜者:" << winner << endl;
}

光点科技
2023-08-15 广告
通常情况下,我们会按照结构模型把系统产生的数据分为三种类型:结构化数据、半结构化数据和非结构化数据。结构化数据,即行数据,是存储在数据库里,可以用二维表结构来逻辑表达实现的数据。最常见的就是数字数据和文本数据,它们可以某种标准格式存在于文件... 点击进入详情页
本回答由光点科技提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式