C::有趣的约瑟夫环

来源:互联网 发布:男科网络咨询说话技巧 编辑:程序博客网 时间:2024/04/26 03:49

   关于约瑟夫环有一个有趣的故事:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏

     当然了,后来我们把它抽象出来,成为著名的约瑟夫环的问题,那么这个问题是怎么解决的呢?别着急,解决步骤如下:

  1)先要建立一个有n个节点的链表,把它变成无头节点的循环链表

  2)确定从谁开始

  3)数到第M个节点,将其删除,循环,直至链表为空

     (PS:注意这里我只放了核心实现代码,如果要进行测试的话将我前面的一篇博客关于单链表的实现结合起来,将这两个核心代码放在里面就可以轻松的实现啦,so easy!吐舌头)

//找尾节点然后将其返回PNode Back(PNode pHead){PNode pTail = pHead;PNode pPreTail = pHead;while(pTail){pPreTail = pTail;pTail = pTail->pNext;}return pPreTail;}//约瑟夫环void JosephCircle(PNode* pHead, int M){int count = 0;PNode pPre = NULL;   //要删除的节点的前一个节点PNode pDel = *pHead;  //要删除的节点(这里从未创建环时的头节点作为起始)if(*pHead == NULL && M<0){return;}Back(*pHead)->pNext = *pHead;  //链接约瑟夫环while(pDel != pDel->pNext){count = M;     //M为走到被删除的节点的步数while(--count)    //查找要删除的节点{pPre = pDel;pDel = pDel->pNext;}pPre->pNext = pDel->pNext;free(pDel);pDel = pPre->pNext;}pDel->pNext = NULL;*pHead = pDel;}


 

 

    

0 0
原创粉丝点击