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 04 Python
跟老齐学Python之有容乃大的list(3)
Sep 15 Python
使用Python脚本操作MongoDB的教程
Apr 16 Python
Python结合ImageMagick实现多张图片合并为一个pdf文件的方法
Apr 24 Python
Python之用户输入的实例
Jun 22 Python
Python爬虫框架scrapy实现的文件下载功能示例
Aug 04 Python
python递归实现快速排序
Aug 18 Python
在pycharm上mongodb配置及可视化设置方法
Nov 30 Python
PyTorch里面的torch.nn.Parameter()详解
Jan 03 Python
python判断两个序列的成员是否一样的实例代码
Mar 01 Python
Flask中sqlalchemy模块的实例用法
Aug 02 Python
python中如何打包用户自定义模块
Sep 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
用js遍历 table的脚本
2008/07/23 Javascript
ext读取两种结构的xml的代码
2008/11/05 Javascript
Javascript 类与静态类的实现
2010/04/01 Javascript
基于JQuery的cookie插件
2010/04/07 Javascript
基于jQuery的Spin Button自定义文本框数值自增或自减
2010/07/17 Javascript
javascript之典型高阶函数应用介绍
2013/01/10 Javascript
再谈Jquery Ajax方法传递到action(补充)
2014/05/12 Javascript
Javascript小技巧之生成html元素
2014/05/15 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
jquery背景跟随鼠标滑动导航
2015/11/20 Javascript
详解Webwork中Action 调用的方法
2016/02/02 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
JS组件Bootstrap Select2使用方法解析
2016/05/30 Javascript
BootStrap 轮播插件(carousel)支持左右手势滑动的方法(三种)
2016/07/07 Javascript
AngularJS教程之简单应用程序示例
2016/08/16 Javascript
微信小程序  wx.request合法域名配置详解
2016/11/23 Javascript
原生Javascript插件开发实践
2017/01/18 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
怎么使用javascript深度拷贝一个数组
2019/06/06 Javascript
简介JavaScript错误处理机制
2020/08/04 Javascript
微信小程序入门之绘制时钟
2020/10/22 Javascript
[03:33]TI9战队采访 - Infamous
2019/08/20 DOTA
Python numpy.array()生成相同元素数组的示例
2018/11/12 Python
Python3之字节串bytes与字节数组bytearray的使用详解
2019/08/27 Python
Html5踩坑记之mandMobile使用小记
2020/04/02 HTML / CSS
惠普加拿大在线商店:HP加拿大
2017/09/15 全球购物
医药营销专业个人自荐信
2013/09/29 职场文书
公司业务员岗位职责
2014/03/18 职场文书
国旗下讲话演讲稿
2014/05/08 职场文书
感恩教师节演讲稿
2014/09/03 职场文书
2015年安康杯竞赛活动总结
2015/03/26 职场文书
结婚典礼致辞
2015/07/28 职场文书
八年级物理教学反思
2016/02/19 职场文书
MongoDB数据库常用的10条操作命令
2021/06/18 MongoDB
如何打开Win11系统注册表编辑器?Win11注册表编辑器打开修复方法
2022/04/05 数码科技