python環(huán)形單鏈表的約瑟夫問題詳解
題目:
一個(gè)環(huán)形單鏈表,從頭結(jié)點(diǎn)開始向后,指針每移動一個(gè)結(jié)點(diǎn),就計(jì)數(shù)加1,當(dāng)數(shù)到第m個(gè)節(jié)點(diǎn)時(shí),就把該結(jié)點(diǎn)刪除,然后繼續(xù)從下一個(gè)節(jié)點(diǎn)開始從1計(jì)數(shù),循環(huán)往復(fù),直到環(huán)形單鏈表中只剩下了一個(gè)結(jié)點(diǎn),返回該結(jié)點(diǎn)。
這個(gè)問題就是著名的約瑟夫問題。
代碼:
首先給出環(huán)形單鏈表的數(shù)據(jù)結(jié)構(gòu):
class Node(object):
def __init__(self, value, next=0):
self.value = value
self.next = next # 指針
class RingLinkedList(object):
# 鏈表的數(shù)據(jù)結(jié)構(gòu)
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 # 指針指向頭結(jié)點(diǎn)
for i in data[1:]:
p.next = Node(i) # 確定指針指向下一個(gè)結(jié)點(diǎn)
p = p.next # 指針滑動向下一個(gè)位置
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):
'''
環(huán)形單鏈表,使用 RingLinkedList 數(shù)據(jù)結(jié)構(gòu),約瑟夫問題。
:param head:給定一個(gè)環(huán)形單鏈表的頭結(jié)點(diǎn),和第m個(gè)節(jié)點(diǎn)被殺死
:return:返回最終剩下的那個(gè)結(jié)點(diǎn)
本方法比較笨拙,就是按照規(guī)定的路子進(jìn)行尋找,時(shí)間復(fù)雜度為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
分析:
我采用了最原始的方法來解決這個(gè)問題,時(shí)間復(fù)雜度為o(m*len(ringlinkedlist))。
但是實(shí)際上,如果確定了鏈表的長度以及要刪除的步長,那么最終剩余的結(jié)點(diǎn)一定是固定的,所以這就是一個(gè)固定的函數(shù),我們只需要根劇M和N確定索引就可以了,這個(gè)函數(shù)涉及到了數(shù)論,具體我就不細(xì)寫了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python深度學(xué)習(xí)pytorch實(shí)現(xiàn)圖像分類數(shù)據(jù)集
這篇文章主要為大家講解了關(guān)于Python深度學(xué)習(xí)中pytorch實(shí)現(xiàn)圖像分類數(shù)據(jù)集的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
python 數(shù)字轉(zhuǎn)換為日期的三種實(shí)現(xiàn)方法
在Python中,我們經(jīng)常需要處理日期和時(shí)間,本文主要介紹了python 數(shù)字轉(zhuǎn)換為日期的三種實(shí)現(xiàn)方法,包含datetime模塊,strftime方法及pandas庫,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
python3.4 將16進(jìn)制轉(zhuǎn)成字符串的實(shí)例
今天小編就為大家分享一篇python3.4 將16進(jìn)制轉(zhuǎn)成字符串的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06
Python利用fastapi實(shí)現(xiàn)上傳文件
FastAPI是一個(gè)現(xiàn)代的,快速(高性能)python?web框架。本文將利用fastapi實(shí)現(xiàn)上傳文件功能,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-06-06
Python使用sqlalchemy實(shí)現(xiàn)連接數(shù)據(jù)庫的幫助類
這篇文章主要為大家詳細(xì)介紹了Python如何使用sqlalchemy實(shí)現(xiàn)連接數(shù)據(jù)庫的幫助類,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考下2024-02-02
python利用paramiko實(shí)現(xiàn)交換機(jī)巡檢的示例
這篇文章主要介紹了python利用paramiko實(shí)現(xiàn)交換機(jī)巡檢,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09
Jupyter Notebook運(yùn)行代碼無反應(yīng)問題及解決方法
這篇文章主要介紹了Jupyter Notebook運(yùn)行代碼無反應(yīng)問題及解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01

