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编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
Jun 20 Python
python的staticmethod与classmethod实现实例代码
Feb 11 Python
python3+PyQt5实现自定义流体混合窗口部件
Apr 24 Python
python从list列表中选出一个数和其对应的坐标方法
Jul 20 Python
Python 通过截图匹配原图中的位置(opencv)实例
Aug 27 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
Oct 18 Python
python标准库sys和OS的函数使用方法与实例详解
Feb 12 Python
python topk()函数求最大和最小值实例
Apr 02 Python
python实现贪吃蛇双人大战
Apr 18 Python
Django用内置方法实现简单搜索功能的方法
Dec 18 Python
用Python仅20行代码编写一个简单的端口扫描器
Apr 08 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
Apache设置虚拟WEB
2006/10/09 PHP
php循环检测目录是否存在并创建(循环创建目录)
2011/01/06 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
简单谈谈PHP中strlen 函数
2016/02/27 PHP
php批量转换文件夹下所有文件编码的函数类
2017/08/06 PHP
悬浮数字的实现案例
2014/02/19 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
2014 HTML5/CSS3热门动画特效TOP10
2014/12/07 Javascript
JQuery操作元素的css样式
2015/03/09 Javascript
jquery实现图片左右切换的方法
2015/05/07 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
AngularJS基础 ng-if 指令用法
2016/08/01 Javascript
AngularJS指令与控制器之间的交互功能示例
2016/12/14 Javascript
微信小程序 navbar实例详解
2017/05/11 Javascript
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
2017/06/25 Javascript
vue.js实现单选框、复选框和下拉框示例
2017/07/18 Javascript
基于webpack 实用配置方法总结
2017/09/28 Javascript
浅谈JsonObject中的key-value数据解析排序问题
2017/12/06 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
2018/05/08 Javascript
Vue下拉框回显并默认选中随机问题
2018/09/06 Javascript
javascript设计模式 ? 备忘录模式原理与用法实例分析
2020/04/21 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
详解Python中的循环语句的用法
2015/04/09 Python
python 基础教程之Map使用方法
2017/01/17 Python
python中利用Future对象异步返回结果示例代码
2017/09/07 Python
Python语言描述机器学习之Logistic回归算法
2017/12/21 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
Python tempfile模块生成临时文件和临时目录
2020/09/30 Python
如何整合JQuery和Prototype
2014/01/31 面试题
高一地理教学反思
2014/01/18 职场文书
文秘档案管理岗位职责
2014/03/06 职场文书
激励员工的口号
2014/06/16 职场文书
一年级班主任工作总结2014
2014/11/08 职场文书
医院保洁员岗位职责
2015/02/13 职场文书
党员干部公开承诺书范文
2015/04/27 职场文书
Java处理延时任务的常用几种解决方案
2022/06/01 Java/Android