问题原由于朋友的一次面试题,面试公司直接给出两道题,要求四十八小时以内作出来,语言不限,作出来以后才能参加接下来的面试。
因而,朋友拿到这套题给咱们看看,本人看到这道题以后,感受挺好玩的,恰好这几天正处在入职前的无聊时期,闲着也是闲着,因而花了两个小时,简单弄了弄。下面是原题目: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:这也从侧面印证了一个结论,那就是学习开发,并无哪门语言好坏之分,学习的是开发的思想,语言只是工具,思想会了,用不一样的工具都能造出本身想要的东西。加油,共勉。学习