约瑟夫环递归方法,python实现约瑟夫环简易代码

  约瑟夫环递归方法,python实现约瑟夫环简易代码

  约瑟夫环问题,这是一个非常经典的算法,处理它的关键是伪链表。

  解释:N个人组成一个圈,从第一个人开始数,报圈到M个人,其余的继续从1开始数,报圈到M个人;来来回回,直到大家都出圈了。(模拟这个过程,输出画圈的人的号码)

  在《数据结构与算法》这本书里,这个是在链表里解决的。我觉得用链表比较麻烦,而且这也不是最好的处理方式。

  为了便于理解,我画了一张图:

  这些问题包括:首先,我们需要考虑。

  1.“圈子”是如何形成的?

  上图就是一个例子。从下标0开始,下标为11时,加1应返回0。

  index=(index 1)% count;2.怎么处理?或者数组列表或者其他方法?

  链表很重,所以用循环排列的方法。

  解决方案方案分析:周期的开始和结束:周期的结束取决于rxdej中是否还有“人”。一个变量alive可以代表最初的人数。Alive-每次循环发生时为1。就判断活着是不是0。

  Is while(alive0)

  每次骑车都会“穿越”人。但是这个人有两种不同的状态。在rxdej而不是在rxdej。在rxdej中,它与报告数量无关,但在number 1和rxdej中,数量保持不变。

  假设有一个n个int元素的数组。每个int元素的意思都是“人”。那么如果值是0和1,那么1表示在rxdej,0表示不在rxdej,那么如果这个人在rxdej,那么数字1;如果这个人不在rxdej,那就是0号。那么在报数字的时候,就不需要考虑这个人是不是在rxdej了。(每个人都需要加1或0,所以请在这里尽量优化程序。

  voidJoseph(intcount,int doom){ int alive=count;//幸存者数量int Number=0;//计数,当number==doom时,消除此人int index=0;//下标,总人数-1 int * circle=NULL;//根据需要设置循环数组(everyone calloc)存储函数应用获得的空间,自动将每个元素初始化为0//。所以0表示这个人在约瑟夫的圈子里,1表示这个人画了一个圈。即“淘汰”circle=(int *)calloc)(sizeof)int)//只要存活人数大于0,循环while(alive 0)number=1-circle(index)//每当轮到一个数的时候,不管是 0 还是 1 ,只要计数if(number==doom) number==doom,当前的人就被淘汰/*淘汰一个人,1。输出此人的位置2 circle[index]=1;活动-;数字=0;(//如果取总人数count和余数,索引会一直在0和count-1之间循环,循环数组的目的索引=(index 1)% count;} printf((n);自由(圆);//结束后一定要给圈子应用释放空间}

  方案二的方案分析:方案二是基于方案一的优化。通过删除圆形节点,可以降低时间复杂度。

  要删除的节点的下标是curIndex,前一个节点的下标是preIndex;

  circle[pre index]=circle[curindex];假设要删除的节点下标curIndex=3是3,那么circle[2]=circle[3],circle[2]=4,在circle[2]之前是3,现在是4。也就是说,下标3的第四个人被删除了。

  怎么穿越?

  preIndex=curIndexcurIndex=circle[curIndex];但是出环时,curIndex和preIndex的变化与上述操作不同。

  CurIndex从轮子里出来的时候需要向后移动。预索引不应移动。

  对于每个周期,直接计数。因为被删除的人(如上面第四个人)不算。

  voidJoseph(intcount,int doom){ int alive=count;//幸存者人数int number=0;//报告数量int curIndex=0;//当前人下标int preIndex=count-1;//前面的人下标int * circle=NULL索引;circle=(int *)malloc(sizeof)int)* count);初始化圆数组的对于(索引=0;索引计数;索引({ circle [ index ]=)索引)% count}而(alive 0){ number;if(number==doom ) {alive==1?printf(%d ,curIndex 1) :printf ) %d ,curIndex 1);活动- -;编号=0;circle[pre index]=circle[curindex];//出局操作} else { preIndex=curIndex//处理下一个人} curIndex=circle[curIndex];(免费(圈);}

  解法三程序分析:解法三里不进行车牌申报数,直接计算需要出行的人数,定位于出圈人。

  num=doom % alive-1;对于(索引=0;index(num==-1?活着-1:纳米;索引({ pre index=curindexcurIndex=circle[curIndex];}voidJoseph(intcount,int doom){ int alive=count;//幸存者人数int curIndex=0;//当前人下标int preIndex=count-1;//前面的人下标int * circle=NULL索引;circle=(int *)malloc(sizeof)int)* count);对于(索引=0;索引计数;索引({ circle [ index ]=)索引)% count//链表的初始化(while(alive0) )//只要有幸存者,就"继续杀" int num=doom % alive - 1计算出需要直接移动的人数,//直接出局的人用于()索引(num==-1?活着-1:纳米;索引({ pre index=curindexcurIndex=circle[curIndex];() /这个人戴上戒指!直播==1?printf(%d ,curIndex 1) :printf ) %d ,curIndex 1);活动- -;circle[pre index]=circle[curindex];//真正的外出操作!curIndex=circle[curIndex];//继续处理下一个人}//该算法比正常约瑟夫c效率提高30%!自由(圈);}

  开源代码库源地址:

  https://github.com/碧青的魔镜259189888/约瑟夫林/

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: