"""A Trie/Prefix Tree is a kind of search tree used to provide quick lookupof words/patterns in a set of words. A basic Trie however has O(n^2) space complexitymaking it impractical in practice. It however provides O(max(search_string, length oflongest word)) lookup time making it an optimal approach when space is not an issue."""classTrieNode:def__init__(self): self.nodes =dict()# Mapping from char to TrieNode self.is_leaf =Falsedefinsert_many(self,words: [str]):""" Inserts a list of words into the Trie :param words: list of string words :return: None """for word in words: self.insert(word)definsert(self,word:str):""" Inserts a word into the Trie :param word: word to be inserted :return: None """ curr = selffor char in word:if char notin curr.nodes: curr.nodes[char]=TrieNode() curr = curr.nodes[char] curr.is_leaf =Truedeffind(self,word:str) ->bool:""" Tries to find word in a Trie :param word: word to look for :return: Returns True if word is found, False otherwise """ curr = selffor char in word:if char notin curr.nodes:returnFalse curr = curr.nodes[char]return curr.is_leafdefdelete(self,word:str):""" Deletes a word in a Trie :param word: word to delete :return: None """def_delete(curr: TrieNode,word:str,index:int):if index ==len(word):# If word does not existifnot curr.is_leaf:returnFalse curr.is_leaf =Falsereturnlen(curr.nodes)==0 char = word[index] char_node = curr.nodes.get(char)# If char not in current trie nodeifnot char_node:returnFalse# Flag to check if node can be deleted delete_curr =_delete(char_node, word, index +1)if delete_curr:del curr.nodes[char]returnlen(curr.nodes)==0return delete_curr_delete(self, word, 0)defprint_words(node: TrieNode,word:str):""" Prints all the words in a Trie :param node: root node of Trie :param word: Word variable should be empty at start :return: None """if node.is_leaf:print(word, end=" ")for key, value in node.nodes.items():print_words(value, word + key)deftest_trie(): words ="banana bananas bandana band apple all beast".split() root =TrieNode() root.insert_many(words)# print_words(root, "")assertall(root.find(word) for word in words)assert root.find("banana")assertnot root.find("bandanas")assertnot root.find("apps")assert root.find("apple")assert root.find("all") root.delete("all")assertnot root.find("all") root.delete("banana")assertnot root.find("banana")assert root.find("bananas")returnTruedefprint_results(msg:str,passes:bool) ->None:print(str(msg), "works!"if passes else"doesn't work :(")defpytests():asserttest_trie()defmain():""">>> pytests() """print_results("Testing trie functionality", test_trie())if__name__=="__main__":main()