链表常见面试题二:约瑟夫环

来源:互联网 发布:淘宝发布宝贝过程好慢 编辑:程序博客网 时间:2024/06/10 20:42

面试题1:约瑟夫环

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

问题:怎样确定16和31的位置

解题思路:

从开始位置遍历,当指针到报数为三的位置上时,将第三个位置的节点删除,然后继续循环删除,直到当前节点(指针指向的节点)的后一个节点的next是当前节点时,即留下两个元素。

如图所示:

wKioL1aggyfCpxJ8AAAaxYGPcKY290.png

pLinkNode JoseCycle(pList *pHead, int num){ assert(pHead); pLinkNode cur = *pHead; pLinkNode del = NULL; int count = 0; while (1) {  count = num;  if (cur == cur->next->next) //当前节点的后一个节点的next是当前节点时,结束循环  {   break;  }    while (--count)    //找到第num个元素   {    cur = cur->next;   }   del = cur->next;   cur->data = cur->next->data;   cur->next = cur->next->next;   free(del); //删除第num个元素   del == NULL; } *pHead = cur; return cur;}

测试函数:

void Test13() // 测试约瑟夫环{ pList l1; int i = 0; InitLinkList(&l1); for (i = 1; i <= 41; i++) {  PushBack(&l1, i); } pLinkNode pos = Find(l1,41);  //查找元素,Find函数在单链表的实现中 pos->next = l1;     //构建环 pos=JoseCycle(&l1,3);    printf(" %d \n", pos->data); printf(" %d \n", pos->next->data);}

wKioL1aghJCyB3L-AAAMWFm-MV8306.png

 

 

0 0
原创粉丝点击