Python实现单链表和字典
本文记录使用Python练习实现单链表和字典的代码
目录结构:
. |-- demo | |-- main.py | |-- src | | |-- my_dict.py | | |-- my_linked_list.py
单链表:
# _*_coding: utf-8 _*_ # https://zhuanlan.zhihu.com/p/60057180 class LinkedListNode(): """链表节点""" def __init__(self, item, next=None): self.item = item self.next = next class SignleLiknedList(): """单向链表""" def __init__(self): self.__header: LinkedListNode = None self.__current_node: LinkedListNode = None self.__count: int = 0 def add(self, node: LinkedListNode) -> None: self.__count += 1 if self.__header is None: self.__header = node self.__current_node = self.__header return self.__current_node.next = node self.__current_node = node def remove(self, node: LinkedListNode) -> bool: if node is None: return False if node is self.__header: self.__header = None self.__count -= 1 return True prev_node = self.__header for item in self.nodes(): if node is item: prev_node.next = node.next if node is self.__current_node: self.__current_node = prev_node node = None self.__count -= 1 return True prev_node = item return False def clear(self): self.__header = None self.__current_node = None def nodes(self): if self.__header is None: return None cur = self.__header while cur is not None: yield cur cur = cur.next @property def header(self): return self.__header @property def tail(self): return self.__current_node @property def count(self): return self.__count
字典:
# _*_coding: utf-8 _*_ # https://mp.weixin.qq.com/s?__biz=MzUyOTk2MTcwNg==&mid=2247486877&idx=1&sn=2c8a3021550666c95007b3f16ea231a9&chksm=fa584a18cd2fc30eecbb156372bce3fa929e39f935efee1d4f6c0b3cbc72ea6cb735428a9630&mpshare=1&scene=1&srcid=0926bBiOoZf8H1BplT1khvpH&sharer_sharetime=1601095103197&sharer_shareid=266dc9451fd28ecaad4697cc057771d2&key=0a19845a51c58415f5e23037fbc78c748ace9ba0a5aaff408c5faabf53c5a340c940294dabd0b4e78af014a0cb939f4ca5f86df138f966f07e9a9ccd19418f9bd5524d1aa7ac2fc257a8ae781dcd18f3335574dcc958120fe0333d34318196127af61fdf3198a7173eaf00a79345938a05215220713204bbbee84e6351423d92&ascene=1&uin=MTI5MDA0NDAwOA%3D%3D&devicetype=Windows+10&version=62070158&lang=zh_CN&exportkey=AZCTq18RYFqS%2BBII%2Bu4pvpU%3D&pass_ticket=Nmlj6bXbHC6L8HV47I7Ld1x7IUpyK6Oqb6DGKPU37iJB0Q8koxVXwnDD%2BCT1aBJh&wx_header=0 from demo.src.my_linked_list import (SignleLiknedList, LinkedListNode) class MyDict(): """自己实现字典结构,非线程安全""" __factor = 0.75 def __init__(self, value_type: type, capacity: int): if value_type is None or type(value_type) is not type: raise ValueError(value_type) if capacity <= 0: raise ValueError(capacity) self.__value_type = value_type self.__capacity = capacity self.__count = 0 self.__buckets = [None for i in range(0, capacity)] @property def count(self) -> int: return self.__count def add(self, key, value) -> None: __entry = __Entry(0, '', '') if type(value) is not self.__value_type: raise TypeError key_hash = hash(key) bucket_no = key_hash % self.__capacity if self.__buckets[bucket_no] is None: self.__buckets[bucket_no] = SignleLiknedList() entry_list: SignleLiknedList = self.__buckets[bucket_no] node = self.__get_entry(key) if node is None: entry = _Entry(key_hash, key, value) entry_list.add(LinkedListNode(entry)) self.__count += 1 else: node.item.value = value if entry_list.count > self.__factor*self.__capacity: self.__reset() def get(self, key: str): node = self.__get_entry(key) return None if node is None else node.item.value def remove(self, key): key_hash = hash(key) bucket_no = key_hash % self.__capacity entry_list = self.__buckets[bucket_no] node = self.__get_entry(key) remove_result = entry_list.remove(node) if remove_result: self.__count -= 1 return remove_result def __reset(self): old_cap = self.__capacity self.__capacity = 2*self.__capacity new_buckets = [None for i in range(0, self.__capacity)] for i in range(0, old_cap): entry_list = self.__buckets[i] if entry_list is None: continue for node in entry_list.nodes(): new_bucket_no = node.item.hash_code % self.__capacity if new_buckets[new_bucket_no] is None: new_buckets[new_bucket_no] = SignleLiknedList() new_entry_list = new_buckets[new_bucket_no] new_entry_list.add(node) self.__buckets = new_buckets def __get_entry(self, key) -> LinkedListNode: if key is None: raise ValueError if type(key) is not str: raise TypeError key_hash = hash(key) bucket_no = key_hash % self.__capacity entry_list = self.__buckets[bucket_no] if entry_list is None: return None for node in entry_list.nodes(): if node.item.hash_code == key_hash and node.item.key == key: return node return None class _Entry(): def __init__(self, hash_code: int, key: str, value): self.__hash_code = hash_code self.__key = key self.__value = value @property def key(self): return self.__key @property def value(self): return self.__value @value.setter def value(self, value): self.__value = value @property def hash_code(self): return self.__hash_code