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的Treq on Twisted来进行HTTP压力测试
Apr 16 Python
简单了解Python中的几种函数
Nov 03 Python
Python yield与实现方法代码分析
Feb 06 Python
Python 函数基础知识汇总
Mar 09 Python
python自动发送测试报告邮件功能的实现
Jan 22 Python
如何使用Python破解ZIP或RAR压缩文件密码
Jan 09 Python
tensorflow 自定义损失函数示例代码
Feb 05 Python
可视化pytorch 模型中不同BN层的running mean曲线实例
Jun 24 Python
Python根据字典的值查询出对应的键的方法
Sep 30 Python
python调用win32接口进行截图的示例
Nov 11 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
Feb 25 Python
使用Python获取字典键对应值的方法
Apr 26 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注入点构造代码
2008/06/14 PHP
为何说PHP引用是个坑,要慎用
2018/04/02 PHP
js防止表单重复提交实现代码
2012/09/05 Javascript
Nodejs为什么选择javascript为载体语言
2015/01/13 NodeJs
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
JavaScript使用function定义对象并调用的方法
2015/03/23 Javascript
javascript中in运算符用法分析
2015/04/28 Javascript
JS封装的选项卡TAB切换效果示例
2016/09/20 Javascript
Vue网页html转换PDF(最低兼容ie10)的思路详解
2017/08/24 Javascript
IntersectionObserver实现图片懒加载的示例
2017/09/29 Javascript
jq源码解析之绑在$,jQuery上面的方法(实例讲解)
2017/10/13 jQuery
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
2017/12/09 Javascript
浅谈jquery fullpage 插件增加头部和版权的方法
2018/03/20 jQuery
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
2019/05/08 Javascript
jQuery 查找元素操作实例小结
2019/10/02 jQuery
vue实现在线预览pdf文件和下载(pdf.js)
2019/11/26 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
[05:24]TI9采访——教练
2019/08/24 DOTA
Python模块WSGI使用详解
2018/02/02 Python
浅谈Python中的bs4基础
2018/10/21 Python
Python二叉树的镜像转换实现方法示例
2019/03/06 Python
Series和DataFrame使用简单入门
2019/11/13 Python
Python unittest单元测试框架及断言方法
2020/04/15 Python
python利用文件时间批量重命名照片和视频
2021/02/09 Python
廉价航班、机票和酒店:JustFly
2018/02/07 全球购物
英国家用电器折扣网站:Electrical Discount UK
2018/09/17 全球购物
Aquatalia官网:意大利著名鞋履品牌
2019/09/26 全球购物
法国低价在线宠物商店:bitiba.fr
2020/07/03 全球购物
家长给孩子的评语
2014/01/30 职场文书
园艺师求职信
2014/03/10 职场文书
2014年党务公开方案
2014/05/08 职场文书
周恩来的四个昼夜观后感
2015/06/03 职场文书
紧急迫降观后感
2015/06/15 职场文书
2015年秋季开学典礼校长致辞
2015/07/16 职场文书
Pytest中skip skipif跳过用例详解
2021/06/30 Python