問題原由於朋友的一次面試題,面試公司直接給出兩道題,要求四十八小時以內作出來,語言不限,作出來以後才能參加接下來的面試。
因而,朋友拿到這套題給咱們看看,本人看到這道題以後,感受挺好玩的,恰好這幾天正處在入職前的無聊時期,閒着也是閒着,因而花了兩個小時,簡單弄了弄。下面是原題目:node
因爲python中不像C語言或者C++裏面那樣有結構體這個東西,因此。。。目前的解決辦法就是使用類去實現相似於結構體這樣的東西。(可是我的感受用類去實現相似結構體的東西有點像是大炮打蚊子。。。佔用資源會不會比結構體誇張不少?)python
class item: def __init__(self,data=None,next=None,age=0): self.data=data # 節點數據 self.next=next # 節點的下一個地址 self.age=age # 節點的age
上面是對這個問題的第一層抽象,也是最底層抽象(定義好數據結構)面試
可是光有這個抽象還不夠,咱們還得本身抽象一層鏈表的操做出來,對於鏈表的基本操做有:算法
固然,這只是對鏈表的一個基本操做的抽象,可能還有一些抽象沒有實現,可是基本能夠完成這個題目中的功能。數據結構
上面抽象出來了一個鏈表的基本操做,可是這個cache還須要知足必定的邏輯:app
處理這些邏輯還須要抽抽象出一層cache來比較好實現。dom
完成上面這三步抽象,剩下的就不難了。函數
# item節點抽象 class item: def __init__(self,data=None,next=None,age=0): self.data=data # 節點數據 self.next=next # 節點的下一個節點 self.age=age # 節點age # 注意,鏈表的0位置存儲的是root節點,不做爲實際存儲信息,裏面的data用來存儲該鏈表長度 class linked_list: def __init__(self): self.root=item(0) # 初始化鏈表,建立鏈表頭,這時候鏈表長度爲0 @property def len(self): # count=0 # item=self.root # while item.next!=None: # item=item.next # count+=1 # return count # count是實際節點個數減一,從0開始 return self.root.data # 上面在鏈表頭中記錄了鏈表長度,就不須要這裏每次計算統計鏈表長度了,直接讀取數據,時間複雜度由O(N)降到了O(1) def append_item(self,data=None): # 模擬python中的列表append數據,將數據插入到鏈表最後並將鏈表長度+1,時間複雜度O(1) append_item_node=item(data) # 初始化插入節點 node=self.root for i in range(self.len): # 找到鏈表結尾,並把新節點插入到最後,而後將鏈表長度+1 node=node.next else: node.next=append_item_node self.root.data += 1 return append_item_node def insert_item(self,num,data=None): # 模擬python中列表插入數據,在某個位置前面插入數據,時間複雜度o(1) insert_item_node=item(data) # 初始化插入節點 node = self.root if num >self.len: # 插入位置超過長度,則直接插入到最後一個元素的前面 num=self.len elif num<1: # 插入位置過小,則直接返回False,插入失敗 return False for i in range(num-1): #找到相應的位置,在該位置前面插入,並將鏈表長度+1 node=node.next else: tmp=node.next node.next=insert_item_node insert_item_node.next=tmp self.root.data += 1 return insert_item_node def remove_item(self,num): # 模擬python中的列表刪除數據,在某個位置刪除數據以後,後面的數據自動往前補,時間複雜度O(1) node=self.root if num < 1 or num > self.len: # 若是刪除位置不在長度範圍內,則返回False,插入失敗 return False for i in range(num-1): # 找到要刪除的節點前一個節點,先用中間變量接收要刪除節點後一個節點,而後再將要刪除的節點刪掉,再將兩段鏈表接起來,最後,鏈表長度-1 node = node.next else: tmp = node.next.next del node.next node.next = tmp self.root.data -= 1 return True def add_allitem_age(self): # 對全部節點的age自加一(只是爲了適應當前題目加的一個方法,通用鏈表中不須要該方法) node=self.root for i in range(self.len): node=node.next node.age+=1 def __iter__(self): # 將鏈表改爲一個迭代器,這樣在外部就可使用for循環遍歷鏈表 self.current_node=self.root return self def __next__(self): # 實現迭代器協議 if self.current_node.next!=None: self.current_node=self.current_node.next return self.current_node raise StopIteration def __str__(self): # 自定義打印改鏈表樣式 node =self.root.next result_str="linked_list:"+str(self.len)+": "+":".join((str(node.data),str(node.age))) for i in range(1,self.len): node=node.next result_str="->".join((result_str,":".join((str(node.data),str(node.age))))) return result_str class cache: def __init__(self,max_num=100): # 初始化cache,生成一個鏈表,並設定好cache最大值 self.data=linked_list() self.max_num=max_num @property def add_age(self): # 每隔一秒鐘須要調用該函數,對鏈表中全部節點age自加一 self.data.add_allitem_age() def insert_item(self,num,data): if self.data.len<self.max_num: # 小於最大值時才讓插入 return self.data.insert_item(num,data) return False def append_item(self,data): if self.data.len<self.max_num: # 小於最大值時才讓追加 return self.data.append_item(data) return False def eliminate(self): # 消除某個節點,可能有知足條件的節點,就消除,沒有就不消除 # 條件:要麼item的age大於10;要麼Cache已滿又無{age>10}的item,則淘汰第一個item num=0 for i in self.data: #循環鏈表,若是找到age大於10的節點,則刪除該節點 num+=1 if i.age>10: self.data.remove_item(num) return True else: # 不然,判斷是否cache已滿,若滿了,則刪除第一個節點,不然什麼都不幹 if self.data.len==100: self.data.remove_item(1) return True else: return False import random import time def simulate_cache(): # 模擬cache cache_obj=cache() # 建立cache對象 for i in range(50): # 放入50個初始化數據到cache中 cache_obj.append_item(i) print(cache_obj.data) # 打印生成50個最初始的值 for i in range(200): # 進行兩百秒的cache動態添加刪除動做 num=random.randint(1,cache_obj.data.len) # 生成隨機數 cache_obj.insert_item(num,num) # 在鏈表隨機位置插入剛生成的隨機數建立的節點 cache_obj.add_age # 將鏈表中每個item節點的age自加一 cache_obj.eliminate() # 調用消除節點方法,自行判斷是否須要刪除某個節點 print(cache_obj.data) # 打印此次處理後鏈表中的數據 time.sleep(1) # 暫停一秒 simulate_cache() # 調用模擬cache函數
第一次用python實現鏈表這樣的數據結構,感受很新奇,花了兩個小時完成這道題,在這也是對本身的一個交代吧。工具
PS:這也從側面印證了一個結論,那就是學習開發,並無哪門語言好壞之分,學習的是開發的思想,語言只是工具,思想會了,用不一樣的工具都能造出本身想要的東西。加油,共勉。學習