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实现端口复用实例代码
Jul 03 Python
python清除字符串里非字母字符的方法
Jul 02 Python
Python程序中的观察者模式结构编写示例
May 27 Python
Python使用QQ邮箱发送Email的方法实例
Feb 09 Python
使用python实现BLAST
Feb 12 Python
python笔记_将循环内容在一行输出的方法
Aug 08 Python
python切片(获取一个子列表(数组))详解
Aug 09 Python
Django框架ORM数据库操作实例详解
Nov 07 Python
python pycharm最新版本激活码(永久有效)附python安装教程
Sep 18 Python
如何基于python3和Vue实现AES数据加密
Mar 27 Python
python 实现波浪滤镜特效
Dec 02 Python
Python类型转换的魔术方法详解
Dec 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之变量、常量学习笔记
2008/03/27 PHP
iis下php mail函数的sendmail配置方法(官方推荐)
2012/04/25 PHP
php中json_decode()和json_encode()的使用方法
2012/06/04 PHP
ThinkPHP CURD方法之order方法详解
2014/06/18 PHP
使用php方法curl抓取AJAX异步内容思路分析及代码分享
2014/08/25 PHP
Laravel 5框架学习之向视图传送数据
2015/04/08 PHP
PHP array_key_exists检查键名或索引是否存在于数组中的实现方法
2016/06/13 PHP
php 魔术常量详解及实例代码
2016/12/04 PHP
Yii框架响应组件用法实例分析
2019/09/04 PHP
javascript仿qq界面的折叠菜单实现代码
2012/12/12 Javascript
DWR实现模拟Google搜索效果实现原理及代码
2013/01/30 Javascript
JavaScript中数组对象的那些自带方法介绍
2013/03/12 Javascript
用js实现trim()的解决办法
2013/04/16 Javascript
JavaScript组件焦点与页内锚点间传值的方法
2015/02/02 Javascript
JavaScript实现的一个倒计时的类
2015/03/12 Javascript
jQuery中通过ajax的get()函数读取页面的方法
2016/02/29 Javascript
AngularJS动态加载模块和依赖的方法分析
2016/11/08 Javascript
通过sails和阿里大于实现短信验证
2017/01/04 Javascript
canvas实现环形进度条效果
2017/03/23 Javascript
javascript中mouseenter与mouseover的异同
2017/06/06 Javascript
Vim快速合并行及vim 将文件所有行合并到一行
2017/11/27 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
2018/07/04 Javascript
javascript事件循环event loop的简单模型解释与应用分析
2020/03/14 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
python实现从ftp服务器下载文件的方法
2015/04/30 Python
Python对ElasticSearch获取数据及操作
2019/04/24 Python
Django实现微信小程序的登录验证功能并维护登录态
2019/07/04 Python
50行Python代码获取高考志愿信息的实现方法
2019/07/23 Python
Python帮你微信头像任意添加装饰别再@微信官方了
2019/09/25 Python
如何删除一个表里面的重复行
2013/07/13 面试题
暑期培训随笔感言
2014/03/10 职场文书
小学优秀学生评语
2014/12/29 职场文书
淘宝好评语句大全
2014/12/31 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
纯 CSS 自定义多行省略的问题(从原理到实现)
2021/11/11 HTML / CSS
Go中使用gjson来操作JSON数据的实现
2022/08/14 Golang