码迷,mamicode.com
首页 > 其他好文 > 详细

Trie树的分析与实现

时间:2015-10-14 00:09:03      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:

 字典树

       又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。(From baike)

它有三个基本性质:

(1)根节点不存储字符
(2)除根节点外每一个节点都只存储一个字符
(3)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串,每个节点的所有子节点包含的字符都不相同。

技术分享

 

Java实现代码(注释详细):

 

  1 package com.wxisme.trietree;
  2 
  3 /**
  4  *Trie树的实现
  5  *@author wxisme
  6  *@time 2015-10-13 下午9:48:30
  7  */
  8 public class TrieTree {
  9     
 10     private final int SIZE = 26;//字符出现的种类数,以所有的小写字母为例
 11     
 12     private int nodeNumber;//子节点的个数
 13     
 14     private int depth;//树的深度
 15     
 16     private TrieNode root;//树根
 17     
 18     public TrieTree() {
 19         this.nodeNumber = 0;
 20         this.depth = 0;
 21         this.root = new TrieNode();
 22     }
 23     
 24     /**
 25      * 节点结构
 26      * @author wxisme
 27      *
 28      */
 29     private class TrieNode {
 30         private char val;//节点值
 31         
 32         private TrieNode son[];//子节点数组
 33         
 34         private boolean isEnd;//是否有以此节点为结束字符的单词
 35         
 36         private int pearNumber;//节点出现的次数
 37         
 38         public TrieNode() {
 39             this.isEnd = false;
 40             this.pearNumber = 0;
 41             this.son = new TrieNode[SIZE];
 42         }
 43     }
 44     
 45     /**
 46      * 向Trie中插入一个word
 47      * @param word
 48      */
 49     public void insert(String word) {
 50         char[] wordChars = word.toCharArray();
 51         
 52         TrieNode node = this.root;
 53         
 54         for(char ch : wordChars) {
 55             int pos = ch - ‘a‘;
 56             //如果相应位置为空则创建
 57             if(node.son[pos] == null) {
 58                 node.son[pos] = new TrieNode();
 59                 node.son[pos].val = ch;
 60                 node.pearNumber = 1;//第一次出现
 61                 this.nodeNumber ++;
 62             }
 63             else {//已经有该字符
 64                 node.pearNumber ++;
 65             }
 66             node = node.son[pos];
 67         }
 68         node.isEnd = true;
 69         this.depth = Math.max(this.depth, word.length());
 70     }
 71     
 72     /**
 73      * 查找是否存在单词word
 74      * @param word
 75      * @return 结果
 76      */
 77     public boolean search(String word) {
 78         char[] wordChars = word.toCharArray();
 79         
 80         TrieNode node = this.root;
 81         
 82         for(char ch : wordChars) {
 83             int pos = ch - ‘a‘;
 84             if(node.son[pos] != null) {
 85                 node = node.son[pos];//继续向下查找
 86             }
 87             else {
 88                 return false;
 89             }
 90         }
 91         
 92         return node.isEnd;
 93     }
 94     
 95     /**
 96      * 查找是否存在以word为前缀的单词,和search()类似,只是不用判断边界。
 97      * @param word
 98      * @return 结果
 99      */
100     public boolean searchPrefix(String word) {
101         char[] wordChars = word.toCharArray();
102         
103         TrieNode node = this.root;
104         
105         for(char ch : wordChars) {
106             int pos = ch - ‘a‘;
107             if(node.son[pos] != null) {
108                 node = node.son[pos];//继续向下查找
109             }
110             else {
111                 return false;
112             }
113         }
114         
115         return true;
116     }
117     
118     /**
119      * 统计单词出现的次数
120      * @param word
121      * @return 结果
122      */
123     public int wordCount(String word) {
124         char[] wordChars = word.toCharArray();
125         
126         TrieNode node = this.root;
127         
128         for(char ch : wordChars) {
129             int pos = ch - ‘a‘;
130             if(node.son[pos] == null) {
131                 return 0;
132             }
133             else {
134                 node = node.son[pos];
135             }
136         }
137         
138         return node.isEnd?node.pearNumber:0;
139     }
140 
141     
142     /**
143      * 统计以word为前缀的单词个数
144      * @param word
145      * @return 结果
146      */
147     public int wordPrefixCount(String word) {
148         char[] wordChars = word.toCharArray();
149         
150         TrieNode node = this.root;
151         
152         for(char ch : wordChars) {
153             int pos = ch - ‘a‘;
154             if(node.son[pos] == null) {
155                 return 0;
156             }
157             else {
158                 node = node.son[pos];
159             }
160         }
161         
162         return node.pearNumber;
163     }
164     
165     /**
166      * 深度优先遍历Trie树
167      * @param root
168      */
169     public void traversal(TrieNode root) {
170         if(root == null) {
171             return;
172         }
173         for(TrieNode node : root.son) {
174             System.out.println(node.val);
175             traversal(node);
176         }
177     }
178 
179     public int getNodeNumber() {
180         return nodeNumber;
181     }
182 
183     public int getDepth() {
184         return depth;
185     }
186 
187     public TrieNode getRoot() {
188         return root;
189     }
190     
191 }

 看一个Leetcode应用:http://www.cnblogs.com/wxisme/p/4875309.html

Trie树的分析与实现

标签:

原文地址:http://www.cnblogs.com/wxisme/p/4876197.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!