链表OJ—环形链表的约瑟夫问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!


提示:以下是本篇文章正文内容,下面案例可供参考

1、环形链表的约瑟夫题目:

著名的Josephus问题

据说著名犹太 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与 Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。

然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

代码演示:

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param n int整型 
 * @param m int整型 
 * @return int整型
 */
 typedef struct ListNode ListNode;
 //申请一个新的节点
 ListNode*ListBuyNode(int x)
 {
    ListNode*node = (ListNode*)malloc(sizeof(ListNode));
    if(node == NULL)
    {
        perror("malloc fail!");
        exit(1);
    }
    node->val = x;
    node->next = NULL;
    return node;
 }
 //创建带环链表
 ListNode*Greatelist(int n)
 {
    //创建链表
    ListNode*phead = ListBuyNode(1);
    ListNode*pTail = phead;
    for(int i=2;i<=n;i++)
    {
        ListNode*node = ListBuyNode(i);
        pTail->next = node;
        pTail = pTail->next;
    }
    //以上只是在创建单链表
    pTail->next = phead;
    return pTail;//有尾节点就能找到头节点,返回头节点的话还要遍历链表才能找到尾节点
 }
 //n:一共有几个人参加游戏
 //m:报数到m的人,自杀(节点释放)
int ysf(int n, int m ) {
    // 创建不带头的单向循环链表
    ListNode*prev = Greatelist(n);
    //对该链表进行约瑟夫游戏
    ListNode*cur = prev->next;//就是头节点
    int count = 1;//从1开始报数
    while(cur->next!=cur)
    {
        if(count == m)
        {
            //删除节点
            //前一个节点指向大后面的节点
            prev->next = cur->next;
            free(cur);
            cur = prev->next;
            count = 1;//从新开始从1报数
        }
        else {
        //继续往下报数
        prev = cur;
        cur = cur->next;
        count++;
        }
    }
    //此链表中只有一个节点
    return cur->val;
}

总结

好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。
不积硅步,无以至千里;不积小流,无以成江海。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值