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实现股市信息下载的方法
Jun 15 Python
python 文件操作删除某行的实例
Sep 04 Python
Python简单读取json文件功能示例
Nov 30 Python
详解python OpenCV学习笔记之直方图均衡化
Feb 08 Python
基于python的图片修复程序(实现水印去除)
Jun 04 Python
python 处理telnet返回的More,以及get想要的那个参数方法
Feb 14 Python
对python中的控制条件、循环和跳出详解
Jun 24 Python
Python加密模块的hashlib,hmac模块使用解析
Jan 02 Python
使用keras2.0 将Merge层改为函数式
May 23 Python
2021年的Python 时间轴和即将推出的功能详解
Jul 27 Python
python输出国际象棋棋盘的实例分享
Nov 26 Python
python图片灰度化处理的几种方法
Jun 23 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
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
2012/01/03 PHP
Zend Framework中的简单工厂模式 图文
2012/07/10 PHP
PHP容易忘记的知识点分享
2013/04/30 PHP
IIS下PHP的三种配置方式对比
2014/11/20 PHP
php生成zip文件类实例
2015/04/07 PHP
详解PHP的Yii框架中组件行为的属性注入和方法注入
2016/03/18 PHP
解决laravel id非自增 模型取回为0 的问题
2019/10/11 PHP
4种Windows系统下Laravel框架的开发环境安装及部署方法详解
2020/04/06 PHP
thinkphp5.1 框架钩子和行为用法实例分析
2020/05/25 PHP
Js动态创建div
2008/09/25 Javascript
jquery $.ajax入门应用二
2008/11/19 Javascript
js或css实现滚动广告的几种方案
2010/01/28 Javascript
基于jQuery实现左右div自适应高度完全相同的代码
2012/08/09 Javascript
js弹出框轻量级插件jquery.boxy使用介绍
2013/01/15 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
JS判断客服QQ号在线还是离线状态的方法
2015/01/13 Javascript
js自定义select下拉框美化特效
2016/05/12 Javascript
微信小程序 获取微信OpenId详解及实例代码
2016/10/31 Javascript
利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换
2017/01/13 Javascript
JavaScript设计模式之调停者模式实例详解
2018/02/03 Javascript
浅谈关于JS下大批量异步任务按顺序执行解决方案一点思考
2019/01/08 Javascript
JavaScript设计模式之装饰者模式实例详解
2019/01/17 Javascript
[04:55]完美世界副总裁蔡玮:DOTA2的自由、公平与信任
2013/12/18 DOTA
[46:20]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python程序员面试题 你必须提前准备!
2018/01/16 Python
15行Python代码带你轻松理解令牌桶算法
2018/03/21 Python
用django-allauth实现第三方登录的示例代码
2019/06/24 Python
python之生产者消费者模型实现详解
2019/07/27 Python
django 微信网页授权登陆的实现
2019/07/30 Python
如何表示python中的相对路径
2020/07/08 Python
Html5游戏开发之乒乓Ping Pong游戏示例(一)
2013/01/21 HTML / CSS
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
Pedro官网:新加坡时尚品牌
2019/08/27 全球购物
高一新生军训感言
2014/03/02 职场文书
银行求职信怎么写
2014/05/26 职场文书
反邪教观后感
2015/06/11 职场文书