C语言 | 约瑟夫问题(猴王争夺战)

这篇具有很好参考价值的文章主要介绍了C语言 | 约瑟夫问题(猴王争夺战)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

约瑟夫问题(单向循环链表的使用)

         约瑟夫问题有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。下面我们将用猴子争大王这一故事以及采用单向循环链表这一方法来进行讲解这一问题。

        设编号为1,2,……n得n个猴子围坐一圈,约定编号为k(k大于等于1并且小于等于n),从1开始报数,数到m的猴子被淘汰。它的下一位继续从1开始报数,数到m的猴子被淘汰,依次类推,最后剩下一个为猴王。

1、根据下图展示,初始化状态:假设n=6,总共有6个人,k=1,从第一个猴开始报数,m=5,每次数五个。

C语言 | 约瑟夫问题(猴王争夺战)

2、第一次报数:从一号开始,数五个数,1-2-3-4-5,数完五个数,五号被淘汰,第一次报数后,剩余猴的数量如下。

C语言 | 约瑟夫问题(猴王争夺战)

3、第二次报数:从被淘汰的五号的下一位开始报数,也就是六号,数五个数,6-1-2-3-4,数数完毕,四号被淘汰,第二次报数后,剩余猴的数量如下。

C语言 | 约瑟夫问题(猴王争夺战)

4、第三次报数:从被淘汰的四号的下一位开始报数,同样是六号,数五个数,6-1-2-3-6,数数完毕,六号被淘汰,第三次报数后,剩余猴的数量如下。

C语言 | 约瑟夫问题(猴王争夺战)

5、第四次报数:从被淘汰的六号的下一位开始报数,也就是一号,数五个数,1-2-3-1-2,数数完毕,二号被淘汰,第四次报数后,剩余猴的数量如下。

C语言 | 约瑟夫问题(猴王争夺战)

6、第五次报数:从被淘汰的二号的下一位开始报数,也就是三号,数五个数,3-1-3-1-3,数数完毕,三号被淘汰,只剩下一号,那么1号就为猴王。

C语言 | 约瑟夫问题(猴王争夺战)

     


       本程序是有关线性表的链式存储结构的应用,通过C语言中提供的结构指针来存储线性表,利用malloc函数动态地分配存储空间。
       约瑟夫环的大小是变化的,因此相应的结点也是变化的,使用链式存储结构可以动态的生成其中的结点,出列操作也非常简单。用单向循环链表模拟其出列顺序比较合适用结构指针描述每个猴:

typedef struct node_t

{

char data;        //数据域

struct node_t *next;     //指针域 ,指针指向自身结构体的类型(存放的下一个节点的地址)

}link_node_t,* link_list_t;   //结构体数据类型,结构体指针类型


struct node_t《-》link_node_t

struct node_t * 《-》link_list_t《-》link_node_t *

解决问题的完整代码如下:

#include <stdio.h>
#include <stdlib.h>
typedef struct node_t
{
    int data;
    struct node_t *next;
}link_node_t,*link_list_t;

int main(int argc, const char *argv[])
{
    link_list_t h=NULL;    //用于指向头结点
    link_list_t pdel=NULL;    //用于指向被删除节点
    link_list_t ptail=NULL;   //用于指向当前链表的尾
    link_list_t pnew=NULL;    //用于指向新创建的节点
    int kill_num;             //数到几淘汰猴子
    int start_num;            //从几号猴子开始
    int all_sum;              //总数
    printf("please input monkey all_sum:");
    scanf("%d",&all_sum);
    printf("please input start_num:");
    scanf("%d",&start_num);
    printf("please input monkey kill_num:");
    scanf("%d",&kill_num);

    h=(link_list_t)malloc(sizeof(link_node_t));
    if(h==NULL)
    {
        printf("error");
        return -1;
    }
    h->data=1;
    h->next=NULL;
    ptail=h;         //尾指针指向当前第一个节点
    for(int i=2;i<=all_sum;i++)
    {

        pnew=(link_list_t)malloc(sizeof(link_node_t));          
        if(pnew==NULL)  //创建新节点
        {
            printf("error");
            return -1;
        }

        pnew->data=i;     //为新节点赋值
        pnew->next=NULL;

        ptail->next=pnew;   //将新节点连接到链表尾部
        ptail=pnew;         //尾指针跟随移动到尾部

    }

    ptail->next=h;           //将头指针保存到链表尾部,形成单向循环链表


    //开始淘汰猴子 
    for(int i=0;i<start_num-1;i++)   //将头指针移动到开始的猴子号码处
        h=h->next;
	//循环进行淘汰猴子
    while(h!=h->next)  //条件不成的时候,就剩一个猴子,只有一个节点  
    {
        for(int i=0;i<kill_num-2;i++)     //将头指针移动到即将删除节点的前一个节点
            h=h->next;

        pdel=h->next;
        h->next=pdel->next;                  //跨过删除节点
        printf("kill %d\n",pdel->data);      //打印被淘汰的猴子
        free(pdel);
        pdel=NULL;
        h=h->next;   //淘汰该猴子后,从下一个节点开始继续开始数,将头指针移动到开始数的地方
    }
    printf("king is %d\n",h->data);         //国王诞生


    return 0;
}
                                                                

运行结果如下:文章来源地址https://www.toymoban.com/news/detail-428575.html

please input monkey all_sum:6 
please input start_num:1
please input monkey kill_num:5
kill 5
kill 4
kill 6
kill 2
kill 3
king is 1

到了这里,关于C语言 | 约瑟夫问题(猴王争夺战)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言数据结构-用链表解决约瑟夫环问题

    只是普通的大学生一枚,不会很牛的技巧和算法,只是在做数据结构作业中的一点感悟和思考。也不知道自己写得对不对,有什么意见和建议都可以直接指出来哦,我虚心接受(低头鞠躬.jpg)...... 试用线性表的链表存储结构来实现约瑟夫(Josephu)问题。约瑟夫问题如下:设有

    2024年02月06日
    浏览(34)
  • C语言---数据结构实验---顺序表的合并---链表的基本操作---重点解析约瑟夫问题

    实验的写法多种多样,但本文并未采用 #define 定义容量的写法,这样写已经是很老旧过时的写法。所有实验主体采用均为动态开辟,后续如果利用 C++ 来写或许会应用更多语法… 本篇展示数据结构的两个实验 其中,重点分析约瑟夫问题 实验中代码的命名风格等均与下方博客

    2024年02月16日
    浏览(35)
  • 约瑟夫问题

    约瑟夫问题是一个经典的数学问题,也是计算机科学中常见的数据结构和算法题目之一。它的形式是:有n个人站成一排,从第一个人开始报数,每次报到m的人出列,直到所有人都出列为止。请问,最后留下的人原来在什么位置上? 这个问题可以用多种方法解决,其中包括使

    2023年04月09日
    浏览(20)
  • 约瑟夫环问题

    n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。 注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n − 1

    2024年02月02日
    浏览(23)
  • 约瑟夫环问题解决

    单链表 实现 错例 在使用malloc函数开辟的空间中,不要进行指针的移动, 因为一旦移动之后可能出现申请的空间和释放空间大小的不匹配 循环链表 单独创建 逐节点创建 约瑟夫环问题 实现方式一: 实现方式二: 删除节点并建立新链表 实现

    2024年02月02日
    浏览(28)
  • 【数据结构与算法】【约瑟夫问题】还在用递归?教你用链表秒杀约瑟夫

     🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏 《数据结构与算法:初学者入门指南》📘📘 本专栏纯属为爱发电永久免费!!! 这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://su

    2024年02月19日
    浏览(30)
  • 神奇的约瑟夫环(C语言)

    约瑟夫环是一个古老而有趣的问题,它涉及人与人之间的生死较量,引发了人们长久以来的思考和探索。这个问题可以通过不同的方式来解决,每种方式都有其独特的优缺点。 使用数组实现约瑟夫环可以简单直观地表示人员的顺序,但受到数组大小静态限制和数据复制的操作

    2024年02月13日
    浏览(24)
  • 循环链表解决约瑟夫环问题

    n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。 n个人围成一圈,很容易可以想到用循环链表解决问题,用结点代表每个人,节点的数据域存储人的编号

    2024年02月07日
    浏览(31)
  • 【算法】约瑟夫环问题解析与实现

    约瑟夫环(Josephus Problem)是一个经典的数学问题,涉及一个编号为 1 到 n 的人围成一圈,从第一个人开始报数,报到某个数字 m 的人出列,然后再从下一个人开始报数,如此循环,直到所有人都出列。本篇博客将详细解析约瑟夫环问题,并使用 Python 实现算法。 在约瑟夫环问

    2024年02月06日
    浏览(34)
  • 4种方法解决约瑟夫环问题

            约瑟夫环问题是大多数编程初学者必须要跨越的一道坎。在第一次见到它的时候,我还是个刚刚学会循环语句的小蒟蒻,而现在的我已经是深陷图论以及各种其他算法的大蒟蒻了(bushi)。可以说,约瑟夫环问题是我从编程基础向编程思维踏出的重要一步。        

    2024年02月12日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包