问题描述
我正在尝试将某些数据结构实现为Python中的类(链接列表,二进制树,尝试等)。对于其中的某些结构,我可以尝试将它们实现为dict-of-dict(例如trie为其子级嵌套了层),也可以将它们实现为具有“ next”变量,该变量包含相同的另一个实例化。对象。
我想知道与将所有子数据存储在成员变量中相比,递归数据结构的优缺点是什么。有速度或内存优势吗?更好的缓存?可读性?
下面是一些示例代码,这些代码说明了我在说什么,但是我对理论上的好处比对我的伪代码的批评更感兴趣:)
class Trie:
def __init__(self) -> None:
self._trie = {}
def insert(self,text: str) -> None:
trie = self._trie
for char in text:
if char not in trie:
trie[char] = {}
trie = trie[char]
trie["END"] = True
def search(self,prefix: str) -> bool:
trie = self._trie
for char in prefix:
if char not in trie:
return False
trie = trie[char]
return True
class RecursiveTrie:
def __init__(self) -> None:
self.children: List[Optional[RecursiveTrie]] = [None] * 26
self.end_of_word = False
def insert(self,key: str) -> None:
"""
If not present,inserts key into trie.
If the key is prefix of trie node,just marks leaf node.
"""
if not key:
self.end_of_word = True
return
index = self.char_to_index(key[0])
if self.children[index] is None:
self.children[index] = RecursiveTrie()
child = self.children[index]
child.insert(key[1:])
def search(self,key: str) -> bool:
""" Search key in the trie. Returns true if key is present in trie. """
if not key:
return True
index = self.char_to_index(key[0])
if self.children[index] is None:
return False
return self.children[index].search(key[1:])
解决方法
IMO的两种方法中,哪种方法实际上取决于要编写的代码是实际的生产代码还是练习。
对于生产代码,您应该使用第一个版本,它较小且易于阅读。它将Dim vardata(30) As Variant
For i = 1 To numberfields
vardata(i) = "hello"
Next i
视为基本的砖块(就像在Python中一样),并且嵌套的dict根本没有问题(考虑到python中的每个对象属性都在dict
中...使用指向的成员乍一看,另一个不使用dict的实例似乎不是一个好主意。
为了理解尝试,第二个版本(不明确地)不依赖于字典,这是用C甚至C ++编写的方式,在该版本中,与dict
相比,数组可能更有意义(应使用基于真实数据和真实生产硬件的性能分析,今天的CPU太复杂了,无法预测复杂算法的性能。
如果您将来需要使用低级语言实现Trie或Trie的变体,那么这些知识将非常有用。
生产型python软件中的第二个版本使同事和/或您自己的生活变得更加艰难。