今�Hの国の呵呵君: [Data Structure]Trie



今�Hの国の呵呵君: [Data Structure]Trie

Trie比哈希和BST更快,尤其是在string很多的情况下,一下是我们的Trie支持的操作:
  • public void put(String key, Value val) 插入一个string和对应的value
  • public Value get(String key) 得到string对应的value,不在trie里的话返回null
  • public boolean containsKey(String key) trie是否含有查询的string
  • private Node delete(Node node, String key, int len) 在trie里删除string,如果string不在trie里的话,什么也不会改变
  • public Iterable<String> keys() 返回trie里所有的key
  • public Iterable<String> keysWithPrefix(String prefix) 返回trie里所有以prefix开头的key
  • public String longestPrefixOf(String key) 找到查询string和trie里所有string的最长公共前缀
  • public String longestKeyAsPrefixOf(String key) 找到查询string和trie里所有string的最长公共前缀,并且前缀要是trie里的单词

下面我们来分析每一个方法的实现:
首先我们要明确trie里每一个字符是存在edge上而不是node上,换句话说是隐式的存在node上的map里。每一个node包含存value的变量和一个map,map的key是字符,value是子节点。如果node对应的val不是null的话,就说明从root到当前节点组成的string是在trie中的

1. put:
  • 如果当前node不是null
    • 如果还没有到stirng的末尾(index < s.length()),把对应的字符和子节点放入map
    • 如果到了string的末尾,更新value
  • 如果当前node是null,创建新node
    • 如果还没有到stirng的末尾(index < s.length()),把对应的字符和子节点放入map
    • 如果到了string的末尾,更新value

2. get:

按照每个字符去找相应的子节点即可,看最后能不能找到。

3. containsKey:

类似get

4. delete
  • key 在 trie 里
    • 如果当前 index 等于 key 的长度
      • 如果当前节点有子结点,把 value 设置为 null,return 当前 node
      • 如果当前节点没有子节点,return null
    • 如果当前 index 小于 key 的长度,子节点的 return 值不为 null,return 当前 node
    • 如果当前 index 小于 key 的长度,子节点的 return 值为 null
      • 如果当前节点只有一个子节点并且 value 为 null,return null
      • 如果当前节点有大于一个子节点,删除要截止在这,更新map,return 当前 node
      • 如果当前节点 value 不为 null,删除要截止在这,更新map, return 当前 node
  • key 不在 trie 里
    • 如果当前 node 等于 null,return null
    • 如果当前  index 等于 key 的长度,value 等于 null,return 当前 node
    • 如果当前  index 小于 key 的长度
      • 如果子节点 return 的值不为 null,return 当前 node
      • 如果子节点 return 的值为null,为了确定子节点是本来就不存在还是被删除了,我们去 map 里找对应的 character
        • 如果找到了,说明是子节点原本是存在的,就按照 key 在 trie里相应的方法删除
        • 如果找不到,说明子节点原本就不存在,key 是 不在 trie 里的,return 当前 node
值得一提的是,trie 的删除操作真正执行删除的操作是 value 赋值为 null,或者更新 map

5. keys

本质上就是一个dfs,如果存的 map 是 tree map,输出可以按照 lexicographical 的顺序

6. keysWithPrefix

先按照prefix get node,然后 dfs

7. longestPrefixOf

根据当前的单词一步一步找就行,直到长度等于 key 的长度,或者没有子节点了

8. longestKeyAsPrefixOf

类似longestPrefixOf,只需要加一个变量记录当前遇到的最长的 key 的长度就行

Read full article from 今�Hの国の呵呵君: [Data Structure]Trie


No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts