python环形单链表的约瑟夫问题详解


Posted in Python onSeptember 27, 2018

题目:

一个环形单链表,从头结点开始向后,指针每移动一个结点,就计数加1,当数到第m个节点时,就把该结点删除,然后继续从下一个节点开始从1计数,循环往复,直到环形单链表中只剩下了一个结点,返回该结点。

这个问题就是著名的约瑟夫问题。

代码:

首先给出环形单链表的数据结构:

class Node(object):
 def __init__(self, value, next=0):
  self.value = value
  self.next = next # 指针

class RingLinkedList(object):
 # 链表的数据结构
 def __init__(self):
  self.head = 0 # 头部

 def __getitem__(self, key):
  if self.is_empty():
   print 'Linked list is empty.'
   return
  elif key < 0 or key > self.get_length():
   print 'The given key is wrong.'
   return
  else:
   return self.get_elem(key)

 def __setitem__(self, key, value):
  if self.is_empty():
   print 'Linked list is empty.'
   return
  elif key < 0 or key > self.get_length():
   print 'The given key is wrong.'
   return
  else:
   return self.set_elem(key, value)

 def init_list(self, data): # 按列表给出 data
  self.head = Node(data[0])
  p = self.head # 指针指向头结点
  for i in data[1:]:
   p.next = Node(i) # 确定指针指向下一个结点
   p = p.next # 指针滑动向下一个位置
  p.next = self.head

 def get_length(self):
  p, length = self.head, 0
  while p != 0:
   length += 1
   p = p.next
   if p == self.head:
    break
  return length

 def is_empty(self):
  if self.head == 0:
   return True
  else:
   return False

 def insert_node(self, index, value):
  length = self.get_length()
  if index < 0 or index > length:
   print 'Can not insert node into the linked list.'
  elif index == 0:
   temp = self.head
   self.head = Node(value, temp)
   p = self.head
   for _ in xrange(0, length):
    p = p.next
   print "p.value", p.value
   p.next = self.head
  elif index == length:
   elem = self.get_elem(length-1)
   elem.next = Node(value)
   elem.next.next = self.head
  else:
   p, post = self.head, self.head
   for i in xrange(index):
    post = p
    p = p.next
   temp = p
   post.next = Node(value, temp)

 def delete_node(self, index):
  if index < 0 or index > self.get_length()-1:
   print "Wrong index number to delete any node."
  elif self.is_empty():
   print "No node can be deleted."
  elif index == 0:
   tail = self.get_elem(self.get_length()-1)
   temp = self.head
   self.head = temp.next
   tail.next = self.head
  elif index == self.get_length()-1:
   p = self.head
   for i in xrange(self.get_length()-2):
    p = p.next
   p.next = self.head
  else:
   p = self.head
   for i in xrange(index-1):
    p = p.next
   p.next = p.next.next

 def show_linked_list(self): # 打印链表中的所有元素
  if self.is_empty():
   print 'This is an empty linked list.'
  else:
   p, container = self.head, []
   for _ in xrange(self.get_length()-1): #
    container.append(p.value)
    p = p.next
   container.append(p.value)
   print container

 def clear_linked_list(self): # 将链表置空
  p = self.head
  for _ in xrange(0, self.get_length()-1):
   post = p
   p = p.next
   del post
  self.head = 0

 def get_elem(self, index):
  if self.is_empty():
   print "The linked list is empty. Can not get element."
  elif index < 0 or index > self.get_length()-1:
   print "Wrong index number to get any element."
  else:
   p = self.head
   for _ in xrange(index):
    p = p.next
   return p

 def set_elem(self, index, value):
  if self.is_empty():
   print "The linked list is empty. Can not set element."
  elif index < 0 or index > self.get_length()-1:
   print "Wrong index number to set element."
  else:
   p = self.head
   for _ in xrange(index):
    p = p.next
   p.value = value

 def get_index(self, value):
  p = self.head
  for i in xrange(self.get_length()):
   if p.value == value:
    return i
   else:
    p = p.next
  return -1

然后给出约瑟夫算法:

def josephus_kill_1(head, m):
  '''
  环形单链表,使用 RingLinkedList 数据结构,约瑟夫问题。
  :param head:给定一个环形单链表的头结点,和第m个节点被杀死
  :return:返回最终剩下的那个结点
  本方法比较笨拙,就是按照规定的路子进行寻找,时间复杂度为o(m*len(ringlinkedlist))
  '''
  if head == 0:
   print "This is an empty ring linked list."
   return head
  if m < 2:
   print "Wrong m number to play this game."
   return head
  p = head
  while p.next != p:
   for _ in xrange(0, m-1):
    post = p
    p = p.next
   #print post.next.value
   post.next = post.next.next
   p = post.next
  return p

分析:

我采用了最原始的方法来解决这个问题,时间复杂度为o(m*len(ringlinkedlist))。
但是实际上,如果确定了链表的长度以及要删除的步长,那么最终剩余的结点一定是固定的,所以这就是一个固定的函数,我们只需要根剧M和N确定索引就可以了,这个函数涉及到了数论,具体我就不细写了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python中使用异步Socket编程性能测试
Jun 25 Python
python中argparse模块用法实例详解
Jun 03 Python
Python数据类型学习笔记
Jan 13 Python
浅析AST抽象语法树及Python代码实现
Jun 06 Python
详解python上传文件和字符到PHP服务器
Nov 24 Python
Python实现购物评论文本情感分析操作【基于中文文本挖掘库snownlp】
Aug 07 Python
python实现在函数图像上添加文字和标注的方法
Jul 08 Python
Python面向对象之多态原理与用法案例分析
Dec 30 Python
Java爬虫技术框架之Heritrix框架详解
Jul 22 Python
如何实现一个python函数装饰器(Decorator)
Oct 12 Python
python 如何执行控制台命令与操作剪切板
May 20 Python
python编写五子棋游戏
May 25 Python
transform python环境快速配置方法
Sep 27 #Python
python如何求解两数的最大公约数
Sep 27 #Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
Sep 27 #Python
python斐波那契数列的计算方法
Sep 27 #Python
python实现汉诺塔算法
Mar 01 #Python
Python3中bytes类型转换为str类型
Sep 27 #Python
python求解数组中两个字符串的最小距离
Sep 27 #Python
You might like
建立文件交换功能的脚本(二)
2006/10/09 PHP
PHP注释语法规范与命名规范详解篇
2018/01/21 PHP
php让json_encode不自动转义斜杠“/”的方法
2020/04/27 PHP
JS获取整个页面文档的实现代码
2011/12/15 Javascript
js setTimeout 常见问题小结
2013/08/13 Javascript
jQuery获取当前对象标签名称的方法
2014/02/07 Javascript
jquery删除数据记录时的弹出提示效果
2014/05/06 Javascript
Jquery Ajax方法传值到action的方法
2014/05/11 Javascript
Javascript访问器属性实例分析
2014/12/30 Javascript
JSONP跨域请求实例详解
2016/07/04 Javascript
js实现功能比较全面的全选和多选
2017/03/02 Javascript
jquery.rotate.js实现可选抽奖次数和中奖内容的转盘抽奖代码
2017/08/23 jQuery
javascript原生封装一个淡入淡出效果的函数测试实例代码
2018/03/19 Javascript
详解Vue.js使用Swiper.js在iOS
2018/09/10 Javascript
node上的redis调用优化示例详解
2018/10/30 Javascript
如何在Vue.js中实现标签页组件详解
2019/01/02 Javascript
详解vue中axios的使用与封装
2019/03/20 Javascript
jQuery zTree插件使用简单教程
2019/08/16 jQuery
vue动态绘制四分之三圆环图效果
2019/09/03 Javascript
微信小程序JS加载esmap地图的实例详解
2019/09/04 Javascript
JavaScript实现拖拽盒子效果
2020/02/06 Javascript
JS中锚点链接点击平滑滚动并自由调整到顶部位置
2021/02/06 Javascript
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
分享Python文本生成二维码实例
2016/01/06 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
python类中super() 的使用解析
2019/12/19 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
以工厂直接定价的传奇性能:Ben Hogan Golf
2019/01/04 全球购物
乌克兰设计师和品牌的服装:Love&Live
2020/04/14 全球购物
大学生职业生涯规划大赛作品(精品)
2014/09/17 职场文书
大学拉赞助协议书范文
2014/09/26 职场文书
个人工作违纪检讨书
2015/05/05 职场文书
2016优秀大学生个人事迹材料范文
2016/03/01 职场文书
五年级作文之想象作文
2019/10/30 职场文书
关于Numpy之repeat、tile的用法总结
2021/06/02 Python
Spring中bean集合注入的方法详解
2022/07/07 Java/Android