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的三目运算符和not in运算符使用示例
Mar 03 Python
python optparse模块使用实例
Apr 09 Python
Python实现读取json文件到excel表
Nov 18 Python
python+opencv轮廓检测代码解析
Jan 05 Python
Python 实现选择排序的算法步骤
Apr 22 Python
解决Python selenium get页面很慢时的问题
Jan 30 Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 Python
Python远程开发环境部署与调试过程图解
Dec 09 Python
python 使用递归回溯完美解决八皇后的问题
Feb 26 Python
python 使用cx-freeze打包程序的实现
Mar 14 Python
Python判断字符串是否为空和null方法实例
Apr 26 Python
python3检查字典传入函数键是否齐全的实例
Jun 05 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
B2K与车机的中波PK
2021/03/02 无线电
PHP IPV6正则表达式验证代码
2010/02/16 PHP
探讨方法的重写(覆载)详解
2013/06/08 PHP
用js怎么把&amp;字符换成&quot;&amp;amp:&quot;
2006/10/19 Javascript
判断目标是否是window,document,和拥有tagName的Element的代码
2010/05/31 Javascript
js 剪切板的用法(clipboardData.setData)与js match函数介绍
2013/11/19 Javascript
JavaScript禁止页面操作的示例代码
2013/12/17 Javascript
JS判断字符串长度的5个方法(区分中文和英文)
2014/03/18 Javascript
JS仿淘宝实现的简单滑动门效果代码
2015/10/14 Javascript
自学实现angularjs依赖注入
2016/12/20 Javascript
js中less常用的方法小结
2017/08/09 Javascript
JS操作时间 - UNIX时间戳的简单介绍(必看篇)
2017/08/16 Javascript
jQuery实现的鼠标拖动浮层功能示例【拖动div等任何标签】
2018/12/29 jQuery
Angular使用ControlValueAccessor创建自定义表单控件
2019/03/08 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
webpack打包html里面img后src为“[object Module]”问题
2019/12/22 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
2020/05/15 Javascript
vue使用vue-quill-editor富文本编辑器且将图片上传到服务器的功能
2021/01/13 Vue.js
对于Python编程中一些重用与缩减的建议
2015/04/14 Python
Python读取一个目录下所有目录和文件的方法
2016/07/15 Python
redis之django-redis的简单缓存使用
2018/06/07 Python
python使用xlrd和xlwt读写Excel文件的实例代码
2018/09/05 Python
详解Python 中sys.stdin.readline()的用法
2019/09/12 Python
Python FTP文件定时自动下载实现过程解析
2019/11/12 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
pytorch 实现在预训练模型的 input上增减通道
2020/01/06 Python
opencv python Canny边缘提取实现过程解析
2020/02/03 Python
详解在Python中使用Torchmoji将文本转换为表情符号
2020/07/27 Python
超酷炫 CSS3垂直手风琴菜单
2016/06/28 HTML / CSS
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
Kickers鞋英国官网:男士、女士和儿童鞋
2021/03/08 全球购物
班主任班级寄语大全
2014/04/04 职场文书
大学开学计划书
2014/04/30 职场文书
三月法制宣传月活动总结
2014/07/03 职场文书
2016年元旦主持词
2015/07/06 职场文书
Python+uiautomator2实现自动刷抖音视频功能
2021/04/29 Python