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