在图示中,键标注在节点中,值标注在节点之下。每一个完整的英文单词对应一个特定的整数。Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的。键不需要被显式地保存在节点中。图示中标注出完整的单词,只是为了演示 trie 的原理。

trie 中的键通常是字符串,但也可以是其它的结构。trie 的算法可以很容易地修改为处理其它结构的有序序列,比如一串数字或者形状的排列。比如,bitwise trie 中的键是一串位元,可以用于表示整数或者内存地址。

Trie树是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

它有3个基本性质:

(1) 根节点不包含字符,除根节点外每一个节点都只包含一个字符。

(2) 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

(3) 每个节点的所有子节点包含的字符都不相同。

基本思想(以字母树为例):
1、插入过程
对于一个单词,从根开始,沿着单词的各个字母所对应的树中的节点分支向下走,直到单词遍历完,将最后的节点标记为红色,表示该单词已插入Trie树。
2、查询过程
同样的,从根开始按照单词的字母顺序向下遍历trie树,一旦发现某个节点标记不存在或者单词遍历完成而最后的节点未标记为红色,则表示该单词不存在,若最后的节点标记为红色,表示该单词存在。

Trie树的实现

字母树的插入(Insert)、删除( Delete)和查找(Find)都非常简单,用一个一重循环即可,即第i 次循环找到前i个字母所对应的子树,然后进行相应的操作。实现这棵字母树,至于Trie树的实现,可以用数组,也可以用指针动态分配,平时为了方便就用数组,静态分配空间。

1.结构定义:

struct Trie
{
Trie *next[26];
bool isWord;
}Root;

2.插入建树方法:

//插入操作(也是构建Trie树)
void insert(char *tar)
{
Trie* head = &Root;
int id;
while(*tar)
{
id = *tar - 'a';
if(head->next[id] == NULL)
head->next[id] = new Trie();
head = head->next[id];
tar++;
}
head->isWord = true;
}

3.搜索查询方法:

//查找
bool search(char *tar)
{
Trie* head = &Root;
int id;
while(*tar)
{
id = *tar - 'a';
if(head->next[id] == NULL)
return false;
head = head->next[id];
tar++;
}
if(head->isWord)
return true;
else
return false;
}

  

至于结点对儿子的指向,一般有三种方法:

1、对每个结点开一个字母集大小的数组,对应的下标是儿子所表示的字母,内容则是这个儿子对应在大数组上的位置,即标号;

2、对每个结点挂一个链表,按一定顺序记录每个儿子是谁;

3、使用左儿子右兄弟表示法记录这棵树。

三种方法,各有特点。第一种易实现,但实际的空间要求较大;第二种,较易实现,空间要求相对较小,但比较费时;第三种,空间要求最小,但相对费时且不易写。

字典树TrieTree的java实现:

package mine.trietree;

import java.util.ArrayList;
import java.util.List; public class TrieTree {
private int SIZE = 26;
private TreeNode root;
TrieTree(){
root = new TreeNode();
}
class TreeNode{
private TreeNode[] son;
private char data;
private boolean isword;
TreeNode(){
son = new TreeNode[SIZE];
data = ' ';
isword = false;
}
}
protected void InsertTreeNode(String str){
TreeNode node = root;
char[] strdata = str.toCharArray();
for(int i = 0;i < str.length(); i++){
int id = strdata[i]-'a';
if(node.son[id]==null){
node.son[id] = new TreeNode();
node.son[id].data = strdata[i];
}
node = node.son[id];
}
node.isword = true;
}
protected boolean IsInDictionary(String str){
TreeNode node = root;
char[] strdata = str.toCharArray();
for(int i = 0;i < str.length(); i++){
int id = strdata[i]-'a';
if(node.son[id]==null)
return false;
node = node.son[id];
}
if(node.isword==false)
return false;
else
return true;
}
public static void main(String[] args) {
TrieTree root = new TrieTree();
root.InsertTreeNode("hello");
root.InsertTreeNode("world");
root.InsertTreeNode("lixiaokun");
root.InsertTreeNode("haoxue");
if(root.IsInDictionary("lixiaokun"))
System.out.println("Yes");
else
System.out.println("No");
if(root.IsInDictionary("haoxue"))
System.out.println("Yes");
else
System.out.println("No");
} }

java完整版:

package mine.trietree;

import java.util.ArrayList;
import java.util.List; public class TrieTree {
private int SIZE = 26;
private TreeNode root;
TrieTree(){
root = new TreeNode();
}
class TreeNode{
private TreeNode[] son;
private char data;
private boolean isword;
private int num;
TreeNode(){
son = new TreeNode[SIZE];
data = ' ';
isword = false;
int num = 0;
}
}
protected void InsertTreeNode(String str){
TreeNode node = root;
char[] strdata = str.toCharArray();
for(int i = 0;i < str.length(); i++){
int id = strdata[i]-'a';
if(node.son[id]==null){
node.son[id] = new TreeNode();
node.son[id].data = strdata[i];
}else
node.son[id].num++;
node = node.son[id];
}
node.isword = true;
}
protected int CountTime(String str){
if(str.length()==0||str==null)
return -1;
char[] strdata = str.toCharArray();
TreeNode node = root;
for(int i = 0;i < str.length(); i++){
int id = strdata[i]-'a';
if(node.son[id]==null)
return 0;
else
node = node.son[id];
}
return node.num;
}
protected boolean IsInDictionary(String str){
TreeNode node = root;
char[] strdata = str.toCharArray();
for(int i = 0;i < str.length(); i++){
int id = strdata[i]-'a';
if(node.son[id]==null)
return false;
node = node.son[id];
}
if(node.isword==false)
return false;
else
return true;
}
protected TreeNode GetRoot(){
return this.root;
}
protected void PreVisit(TreeNode node){
if(node!=null){
System.out.print(node.data+" ");
for(TreeNode temp:node.son)
PreVisit(temp);
}
}
public static void main(String[] args) {
TrieTree root = new TrieTree();
root.InsertTreeNode("hello");
root.InsertTreeNode("world");
root.InsertTreeNode("lixiaokun");
root.InsertTreeNode("haoxue");
root.InsertTreeNode("helloworld");
root.InsertTreeNode("comeon");
root.InsertTreeNode("hehehe");
if(root.IsInDictionary("lixiaokun"))
System.out.println("Yes");
else
System.out.println("No");
if(root.IsInDictionary("haoxue"))
System.out.println("Yes");
else
System.out.println("No");
if(root.IsInDictionary("hehe"))
System.out.println("Yes");
else
System.out.println("No");
root.PreVisit(root.GetRoot());
System.out.println();
System.out.println(root.CountTime("he"));
} }

  

文字引用自:http://www.cnblogs.com/archimedes/p/trie-tree.html

字典树(Trie Tree)的更多相关文章

  1. 字典树Trie Tree

    又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀 ...

  2. [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序

    一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 ...

  3. 字典树trie学习

    字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...

  4. 『字典树 trie』

    字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...

  5. 字典树(Trie)详解

    详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...

  6. 字典树(Trie树)实现与应用

    一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...

  7. [转载]字典树(trie树)、后缀树

    (1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...

  8. Codevs 4189 字典(字典树Trie)

    4189 字典 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 传送门 题目描述 Description 最经,skyzhong得到了一本好厉害的字典,这个字典里 ...

  9. 字典树trie

    字典树经常用于单词搜索,现在网络引擎中也应用了trie树: public class Trie{ private int SIZE = 26; private TrieNode root; Trie( ...

随机推荐

  1. torch7安装

    按照官网进行安装即可;(http://torch.ch/docs/getting-started.html#_) # in a terminal, run the commands WITHOUT s ...

  2. jquery尺寸:宽度与高度

    width() 方法设置或返回元素的宽度(不包括内边距.边框或外边距). height() 方法设置或返回元素的高度(不包括内边距.边框或外边距). innerWidth() 方法返回元素的宽度(包括 ...

  3. WPF三种基本触发器与【与或】逻辑触发器

    wpf中的触发器是应用于程序界面模板.样式.皮肤.主题的基础.以下作为学习的记录. 1,三种基本触发器,属性触发器.数据触发器.事件触发器 属性触发器 <!--属性触发器--> <T ...

  4. 本BLOG简介(内有一道UVa524素数环进阶版)【B001】

    [B001]Hi,大家好,今天我的博客第一天开通,今天奉上开博题,出自首都师师范大学附属中学OJ(题号未知在练习场中)原题为UVa524,题目要求如下: [难度B]—————————————————— ...

  5. HowTo:使用数据流读写消息

      本文主要演示使用TPL 数据流库从数据流块(dataflow block)读写消息. 提供了同步方法和异步方法. 主要使用BufferBlock,其既能作为message source,有能作为m ...

  6. HTML5 postMessage 和 onmessage API 详细应用

    随着 HTML5 的发展,了解并熟悉 HTML5 的 API 接口是非常重要的.postMessage(send) 和 onmessage 此组 API 在 HTML5 中有着广泛的应用,比如 Web ...

  7. CSS z-index 属性的使用方法和层级树的概念

    之前有一篇文章提到过z-index,我们知道只有在元素设置了position部位static时才生效,而且z-index也跟父元素有关系,今天就在ie7遇到类似问题,在网上查了一些资料,发现一篇好文章 ...

  8. 【poj2828】Buy Tickets

    Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get ...

  9. 递归函数的用法及array_merge的用法

    $info=M('navclass')->select(); function getAllArray($data, $pid =1) { $arr = array(); foreach ($d ...

  10. linux系统下yum源的搭建

    1.建立挂载点 系统默认在 /mnt目录 1>创建挂载点 mkdir -p /mnt/cdrom   参数-p是需要时创建目标目录的上层目录,但即使这些目录已存在也不当作错误处理 2>查看 ...