问题描述:
假设有n个人围坐一圈,现在要求从第k个人开始报数,报到第m个数的人出列,然后从下一个人继续开始以同样的方法报数,直到所有的人都出列为止,要求按顺序输出各出列的人的编号。
算法设计:
1)建立包含指定节点的循环链表,可以先创建一个空表,然后再尾部逐渐加入元素。
2)循环计数,找到并删除应该退出的节点。
代码实现:
#首先定义一个结点类
class LNode:
def __init__(self,elem,next_=None):
self.elem=elem
self.next=next_
#再定义一个循环链表类
class LCList:
#初始化尾结点
def __init__(self):
self._rear=None
#判断是否为空
def is_empty(self):
return self._rear is None
#从前端插入数据
def prepend(self,elem):
p=LNode(elem)
if self._rear is None:
p.next=p
self._rear=p
else:
p.next=self._rear.next
self._rear.next=p
#从尾端插入
def append(self,elem):
self.prepend(elem)
self._rear=self._rear.next
#从前端弹出元素
def pop(self):
if self._rear is None:
raise ValuError('in pop of CLList')
p=self._rear.next
if self._rear is p:
self._rear=None
else:
self.rear.next=p.next
return p.elem
#输出所有表元素
def printall(self):
if self.is_empty():
return
p=self._rear.next
while p is not self._rear:
print(p.elem)
p=p.next
#定义约瑟夫环类,继承自循环链表类
class josephus(LCList):
#定义一个新方法用于实现结点环的循环
def turn(self,m):
for i in range(m):
self._rear=self._rear.next
def __init__(self,n,k,m):
super().__init__()
for i in range(n):
self.append(i+1)
#从第k个人开始报数,将此元素移动到表头
self.turn(k-1)
#开始循环报数
while not self.is_empty():
self.turn(m-1) #把报数到m人移动到表头
p=self.pop()
print(p,end='\n' if self.is_empty() else ', ')
版权声明:本文为weixin_44467002原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。