美文网首页数据结构
链表运用---约瑟夫问题(一)

链表运用---约瑟夫问题(一)

作者: 王小丫子 | 来源:发表于2019-02-18 19:05 被阅读0次

约瑟夫问题又称为“约瑟夫置换”或者“约瑟夫环”,是一个出现在计算机科学和数学中的问题
历史背景:
版本一:这个问题是以[弗拉维奥·约瑟夫]命名的,他是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个
版本二:Josephus有过的故事:39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓。于是决定了自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀。然后下一个重新报数,直到所有人都自杀身亡为止。然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏
【ps:发现了数据结构&算法何其伟大,关乎到生死存亡呀哈哈哈】
应用问题转化:
【N个人围绕在一个圆桌子上玩报数游戏,报到N这个数字,淘汰,然后从下一个人继续开始报数,报到N淘汰,循环下去,最后剩余2个人,也
可以循环,最终只会有一个人胜出】
言归正传:怎么使用循环链表来描述这个问题?可直接参考如下代码

/*****************************************循环链表*******************************************/
void circularLinkedList(int M,int N){
    PersonListNode *head = (PersonListNode *)malloc(sizeof(PersonListNode));//定义一个头结点
    head ->next = head;
    head ->num = 1;
    
    PersonListNode *temp = head;    //将头结点复制给temp
    
    for (int i = 2; i<= N; i++) {//构建循环链表,
        temp ->next = (PersonListNode *)malloc(sizeof(PersonListNode)); // 当i=2时,temp->next为开始结点,也就是头结点的下一个结点
        temp = temp->next; // 当i=2时,将开始结点赋值给temp
        temp->num = i;
        temp->next = head; // 将当前结点指向头结点,循环结束时,temp指向的是尾结点
    }
    while (temp != temp ->next) {//循环开始时,temp指向的是尾结点
        for (int j=1; j<M; j++) {
            temp =temp->next;//此时在M的间隔中间,只需要完成结点替代、遍历
        }
        //执行完for时就说明此时j=M,该俘虏需要自杀,for循环执行完,当前temp的下一个人就是目标俘虏
        PersonListNode *targetPersonNode = temp->next;
        cout<<"编号为"<<targetPersonNode->num<<"的俘虏自杀"<< endl;
        //此时需要将自杀俘虏之后俘虏与自杀俘虏之前的俘虏进行关联,此时的temp为自杀前一个俘虏的结点
        temp->next = temp->next->next;
        free(targetPersonNode);//将当前自杀的俘虏移除,重新来过
    }
    cout<<"此时胜出俘虏编号为"<< temp->num<<endl;
}

int main()
{
    int M,N;//M 规则(隔M个数) N 人数(N个人)
    cout << "输入俘虏人数N " <<endl;
    cin >> N;
    cout << "输入规则M间隔数"<<endl;
    cin >> M;
    //单链表实现思路[目前有点问题,待完善]
//    singleLinkedList(M, N);
    //循环链表实现思路。M为3 N为8 此时7号俘虏胜出
    circularLinkedList(M,N);
    
    return 0;
}

待完善【单链表解法、数组解法 及其对比】

相关文章

网友评论

    本文标题:链表运用---约瑟夫问题(一)

    本文链接:https://www.haomeiwen.com/subject/geszeqtx.html