Java Trie(词典树)实现

实现Trie tree,可用作实现词典。可用来存储,查找及删除string, 同时实现返回前缀为指定字符所有结果的功能。

每个node存所有child节点与及对应path上的字符所组成的map,利用count来记录每个节点的子树种存在多少word,便于删除的操作。

findAllWithPrefix 用到了DFS的思想,遍历所有带有前缀的结果并输出。常见应用于搜索引擎中。

  1 class TrieNode {
  2     int count;
  3     Map<Character, TrieNode> children;
  4     boolean isWord;
  5     public TrieNode() {
  6         count=0;
  7         isWord=false;
  8         children=new HashMap<Character,TrieNode>();
  9     }
 10 }
 11 
 12 public class MyTrie {
 13     TrieNode root;
 14 
 15     public MyTrie() {
 16         root = new TrieNode();
 17     }
 18 
 19     public boolean search(String s) {
 20         if (this.root == null || s == null || s.length() == 0) {
 21             return false;
 22         }
 23         TrieNode cur=root;
 24         for (int i = 0; i < s.length(); i++) {
 25             TrieNode next=cur.children.get(s.charAt(i));
 26             if(next == null) {
 27                 return false;
 28             }
 29             cur=next;
 30         }
 31         return cur.isWord;
 32     }
 33     public void insert(String s) {
 34         if(search(s) || s == null || s.length() == 0) {
 35             return;
 36         }
 37         TrieNode cur=root;
 38         for (int i = 0; i < s.length(); i++) {
 39             TrieNode next=cur.children.get(s.charAt(i));
 40             if(next == null) {
 41                   next=new TrieNode();
 42                   cur.children.put(s.charAt(i), next);
 43             }
 44             cur=next;
 45             cur.count++;
 46         }
 47         cur.isWord=true;
 48     }
 49     public boolean delete(String s) {
 50         if(!search(s)) {
 51             return false;
 52         }
 53         TrieNode cur=root;
 54         for(int i=0; i<s.length(); i++) {
 55             TrieNode next=cur.children.get(s.charAt(i));
 56             if(next.count == 1) {
 57                 cur.children.remove(s.charAt(i));
 58                 return true;
 59             }
 60             next.count--;
 61             cur=next;
 62         }
 63         cur.isWord=false;
 64         return true;
 65     }
 66     
 67     public List<String>findAllWithPrefix(String s){
 68         TrieNode matchNode=searchNode(s);
 69         if(matchNode == null) {
 70             return null;
 71         }
 72         List<String>result=new ArrayList<String>();
 73         DFS(result, matchNode, new StringBuilder(s));
 74         return result;
 75     }
 76     private void DFS(List<String>result, TrieNode matchNode, StringBuilder sb) {
 77         if(matchNode.isWord == true) {
 78             result.add(sb.toString());
 79         }
 80         for(Map.Entry<Character, TrieNode>child : matchNode.children.entrySet()) {
 81             sb.append(child.getKey());
 82             DFS(result,child.getValue(),sb);
 83             sb.deleteCharAt(sb.length()-1);
 84         }
 85     }
 86     private TrieNode searchNode(String s) {
 87         if(s == null || s.length() == 0) {
 88             return null;
 89         }
 90         TrieNode cur=root;
 91         for(int i=0; i<s.length(); i++) {
 92             TrieNode next=cur.children.get(s.charAt(i));
 93             if(next == null) {
 94                 return cur;
 95             }
 96             cur=next;
 97         }
 98         return cur;
 99     }
100 }

 

posted @ 2017-10-29 13:06  想做码农的熊孩子  阅读(432)  评论(0编辑  收藏  举报