如何使用python从三个角度解决约瑟夫问题

  介绍

小编给大家分享一下如何使用python从三个角度解决约瑟夫问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!

<强> 0写在前面

约瑟夫问题是数据结构教材中的一个常见实例,其问题可以描述为:

设nnn个人围坐一圈,现在要求从第三k党个人开始报数,报到第嗯个的人退出。然后从下一个人开始继续按照同样规则报数并退出,直到所有人退出为止。要求按照顺序输出每个人的序列号。

<强> 1基于数组概念的解法

首先考虑基于python的列表和固定大小的数组概念,即将列表看作元素个数固定的对象,只改变值而不删除元素,相当于摆了一圈nnn把椅子,人虽然退出但是椅子还在,我们可以给每个人从111年到nnn编的号,没有人的位置用000表示,思路如下:

初始

<李>

建立包含nnn个人(编号)的列表

<李>

找到第三k党个人开始

运行

<李>

从三k党的位置开始数到嗯,中间遇到000的就跳过

<李>

数到嗯之后,将其值改为000

<李>

然后继续循环,总共循环nnn次(因为每次循环就会退出一个人)

代码如下:

def  josephus_A (n, k,米):   people 才能=,列表(范围(1),(n + 1)))   小姐:才能=k - 1   for 才能;num 拷贝范围(n):   ,,,count =0   ,,,while  count  & lt;, m:,   ,,,,,if 人[我],祝辞,0:   ,,,,,,,count  +=1   ,,,,,if  count ==, m:   ,,,,,,,印刷(人(我),结束=?”)   ,,,,,,,的人(我),=0   ,,,,,小姐:=,(i + 1), %, n  #,数只是国旗,真正记的数是我   ,,,if  num  & lt;, n - 1:   ,,,,,印刷(=?,,,)   ,,,:   ,,,,,印刷(“,“)

<强> 2基于顺序表的解法

顺序表是线性表的一种,即表中元素放在一块足够大的连续存储区里,首元素存入存储区开始位置,其余元素依次存放。顺序表在python中的也是列表,跟第一种解法不同,当第嗯个人退出需要进行删除元素的操作,才是顺序表。而第一种解法的数组想要删除并不是那么容易,这里是因为python中没有内置对数组的支持,所以用列表代替,具体可以参照c++中的数组,如果要删除中间的某个元素的话,必须对后面的元素重新编号。代码实现如下:

def  josephus_L (n, k,米):   people 才能=,列表(范围(1),(n + 1)))   我才能=k - 1   for 才能;num 拷贝范围(n, 0,1):   ,,,i=% num (i + m - 1)   ,,,print (people.pop(我),结束=?,,,if  num> 1, else “\ n")

<强> 3基于循环单链表的解法

单链表即单向链接表,典型的就是c++中的链表,循环单链表就是头尾相连的单链表,也是线性表的一种,这道题目使用循环单链表记录nnn个人围坐一圈最为契合。我们只需要数到第嗯个结点就删除,删除操作对于链表来说比较容易,而且不需要有我=(i + 1) % n这样的整除操作。但是问题在于python并没有像c++那样有内置对链表的支持,因此需要建立一个链表的类,建立是比较麻烦的,但是操作比较简单,如下:

class  LNode:, #,建立链表结点   def 才能;__init__(自我,elem next_=None):   ,,,self.elem=elem   ,,,self.next=next_   class  LCList: #,建立循环链接表   def 才能__init__(自我):   ,,,self._rear=没有   def 才能is_empty(自我):   ,,,return  self._rear  is 没有   def 才能预谋(自我,elem):, #,前端插入   ,,,p=LNode (elem)   ,,,if  self._rear  is 没有:   ,,,,,p.next=p  #,建立一个结点的环   ,,,,,self._rear=p   ,,,:   ,,,,,p.next=self._rear.next   ,,,,,self._rear.next=p   def 才能添加(自我,elem):, #,尾端插入   ,,,self.prepend (elem)   ,,,self._rear =self._rear.next   def 才能;流行(自我):,#,前端弹出   ,,,if  self._rear  is 没有:   ,,,,,raise  LinkedListUnderflow (“pop 拷贝;of  CLList")   ,,,p =self._rear.next   ,,,if  self._rear  is  p:   ,,,,,self._rear =没有   ,,,:   ,,,,,self._rear.next=p.next   ,,,return  p.elem   def 才能printall(自我):,#,输出表元素   ,,,if  self.is_empty ():   ,,,,,回来   ,,,p =self._rear.next   ,,,while 正确的:   ,,,,,印刷(p.elem)   ,,,,,if  p  is  self._rear:   ,,,,,,,休息   ,,,,,p=p.next   class  LinkedListUnderflow (ValueError): #,自定义异常   ,通过   class 约瑟夫(LCList):   def 才能__init__(自我,n, k, m):   ,,,LCList.__init__(自我)   ,,,for 小姐:拷贝范围(n):   ,,,,,self.append (i + 1)   ,,,self.turn (k - 1)   ,,,while  not  self.is_empty ():   ,,,,,self.turn (m - 1)   null   null   null   null

如何使用python从三个角度解决约瑟夫问题