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 相关文章推荐
pyenv命令管理多个Python版本
Mar 26 Python
python爬虫入门教程--正则表达式完全指南(五)
May 25 Python
Python获取当前页面内所有链接的四种方法对比分析
Aug 19 Python
python的paramiko模块实现远程控制和传输示例
Oct 13 Python
Python编程实现二分法和牛顿迭代法求平方根代码
Dec 04 Python
根据DataFrame某一列的值来选择具体的某一行方法
Jul 03 Python
python实现移位加密和解密
Mar 22 Python
详解Python读取yaml文件多层菜单
Mar 23 Python
Django框架实现的分页demo示例
May 25 Python
pandas实现DataFrame显示最大行列,不省略显示实例
Dec 26 Python
Python小白不正确的使用类变量实例
May 29 Python
Pycharm Plugins加载失败问题解决方案
Nov 28 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
swfupload 多文件上传实现代码
2008/08/27 PHP
mysql下创建字段并设置主键的php代码
2010/05/16 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
php实现网站文件批量压缩下载功能
2015/10/28 PHP
PHP魔术方法以及关于独立实例与相连实例的全面讲解
2016/10/18 PHP
PHP yii实现model添加默认值的方法(两种方法)
2016/11/10 PHP
微信公众号实现会员卡领取功能
2017/06/08 PHP
php7 参数、整形及字符串处理机制修改实例分析
2020/05/25 PHP
JavaScript 克隆数组最简单的方法
2009/02/12 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
js实现iframe自动自适应高度的方法
2015/02/17 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
jquery实现页面常用的返回顶部效果
2016/03/04 Javascript
jQuery如何防止Ajax重复提交
2016/10/14 Javascript
Vue.js 图标选择组件实践详解
2018/12/03 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
Python利用多进程将大量数据放入有限内存的教程
2015/04/01 Python
python基础_文件操作实现全文或单行替换的方法
2017/09/04 Python
对Python 语音识别框架详解
2018/12/24 Python
Python两台电脑实现TCP通信的方法示例
2019/05/06 Python
python使用百度文字识别功能方法详解
2019/07/23 Python
Python yield生成器和return对比代码实例
2020/04/20 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
2020/11/05 Python
纯CSS3制作的鼠标悬停时边框旋转
2017/01/03 HTML / CSS
Agoda中文官网:安可达(低价预订全球酒店)
2021/01/18 全球购物
会计系毕业个人自荐信格式
2013/09/23 职场文书
日语系毕业生推荐信
2013/11/11 职场文书
2014庆六一活动方案
2014/03/02 职场文书
公证委托书
2014/08/01 职场文书
中学生思想品德评语
2014/12/31 职场文书
同学会邀请函模板
2015/01/30 职场文书
人事任命通知书
2015/04/21 职场文书
2015年学校禁毒工作总结
2015/05/27 职场文书
城南旧事观后感
2015/06/11 职场文书
解析Java中的static关键字
2021/06/14 Java/Android