Introduction

介绍

Trie,又称单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。

Trie is an ordered tree data structure that uses strings as keys. Unlike Binary Trees, Tries do not store keys associated with the node. The key is actually determined based on the position of the node on the tree. Any descendants of a node shares a common prefix of the key string associated with that node. Hence, trie is also called as Prefix Tree. The word "trie" comes from Retrieval, and it is pronounced as "try".

Trie是一种以字符串为键的有序树状数据结构,与二叉树不同的是, Trie并不会存储节点键值,节点键值是被节点在树状数据结构中的位置所决定的。一个特定节点的所有子孙的键值都有一个公共的前缀字符,所有Trie也被称为前缀树。 单词“Trie”来自于英文单词“Retrieve”,其发音与单词“Try”相同。

Since this data structure is a prefix tree, trie is commonly used in Dictionaries, Phone Directories and matching algorithms. Trie is best-suited for phone directory (any matching application for that matter) because it is very efficient in matching strings.

因为这个数据结构是一个前缀树,Trie通常被用在字典算法中,尤其电话号码目录的匹配算法中。在字符串匹配中Trie是非常高效的,对于电话号码目录是非常适合的。

So I have decided to implement Trie myself in C#. I have created three classes:

所以我决定使用C#来实现一个Trie数据结构,定义了以下一些类:

  • Node: Represents a single tree node;
  • Node:树节点类;
  • NodeCollection: Represents the children of a node;
  • NodeCollection:树节点结合类;
  • Trie: Trie implementation to insert and search nodes.
  • Trie:Trie类实现了节点的查找以及插入操作。

Implementation

实现

Node: Node represents a basic tree node. Node implements both Depth First and Breadth First algorithms to search its children. It also contains its Parent node and Children node. Node has a key and a Value. Key contains the single character and the value has the actual value of the node. The actual key of the node will be determined by suffixing the single character to its parent's key. Node has a special property called IsTerminal. This property is set to true if the key or a value represents a complete string.

Node:Node类代表了一个基本的节点类,该类同时实现了深度优先和广度优先的子节点查找算法,该类包含了对父节点以及子节点的引用。Node类有两个属性Key和Value,Key是一个单个字符,节点类真正的键值是以其Key属性为后缀,然后依次加上其父节点的Key属性。另外Node还有一个属性叫IsTerminal,来表明其Value或者Key是否表示了一个完整的字符串。

See the picture below:

参见下面的图片:

NodeCollection: This class is a simple collection class which implements the IEnumerable interface for iteration operations. This class contains an internal List class of type Node. NodeCollection implements the standard list methods such as Add( ), Contains( ), Remove( ) etc.

NodeCollection:该类是一个简单的集合类型,实现了用于枚举的IEnumerable接口,其内部包含了一个List<Node>类型,支持一些集合类的标准操作例如添加,删除以及判断是否包含指定节点等等操作。

Trie: This class implements the Trie algorithms such as Insert and Find methods.

Trie:该类实现了Trie算法,实现了插入和查找操作。

示例代码:

//Inserts Names into the Trie data structure
public static Node InsertNode(string name, Node root)
{
    //Is name null?
    if (string.IsNullOrEmpty(name))
        throw new ArgumentNullException("Null Key");

//set the index, start inserting characters
    int index = 1;

//key
    string key;

//start with the root node
    Node currentNode = root;

//loop for all charecters in the name
    while (index <= name.Length)
    {
        //get the key character
        key = name[index - 1].ToString();

//does the node with same key already exist?
        Node resultNode = currentNode.Children.GetNodeByKey(key);

//No, this is a new key
        if (resultNode == null)
        {
            //Add a node
            Node newNode = new Node(key, name.Substring(0, index));

//If reached the last charaecter, this is a valid full name
            if (index == name.Length)
                newNode.IsTerminal = true;

//add the node to currentNode(i.e. Root node for the first time)
            currentNode.Children.Add(newNode);

//set as the current node
            currentNode = newNode;
        }
        else
        {
            //node already exist, set as tghe current node
            //and move to the next character in the name
            currentNode = resultNode;
        }
        //move to the next character in the name
        index++;
    }
    //all done, return root node
    return root;
}

The Insert method inserts the string as one character at a time. It starts with the first character; if the first character doesn't already exist in the root node it adds a new node with the new character and returns the new node. Otherwise it returns the node with the fist character for adding remaining characters. It loops until it adds the entire string. Once it reaches the last character, it marks that node as a terminal node because this node represents a complete string in the tree hierarchy.

插入操作再插入一个字符串的时候,从第一个字符开始,每次只处理一个字符;如果第一个字符在根节点的子节点中没有存在,那么会使用该字符添加一个新的节点然后返回,否则返回已经存在的节点,然后依次循环后面的字符串。一旦到达最后一个字符串,就会标识该节点为一个终止节点(IsTerminal为True),因为在整个树结构上其表示了一个完整的字符串。

The Find methods is implemented by Depth First search algorithm. The tree is searched until the complete string is found. Below is the code.

查找方法实现了深度优先的查找算法,整个树形数据结构将被查找直至该字符串被找到。下面是示例代码:

//Find a node given the key("Jo")
public static bool Find(Node node, string key){

//Is key empty
    if (string.IsNullOrEmpty(key))
        return true;//terminal Node

//get the first character
    string first = key.Substring(0, 1);

//get the tail: key - first character
    string tail = key.Substring(1);
    Node curNode = node.Children.GetNodeByKey(first);

//loop until you locate the key i.e. "Jo"
    if (curNode != null)
    {
        return Find(curNode, tail);
    }
    else
    {
        //not found, return false
        return false;
    }
}

I've attached the entire source code above. The source code contains the Trie class library and a console application to test the Trie library. The console application loads a set of names (stored in names.txt in debug folder) in to the tree and provides options to run Depth First & Breadth First algorithm. The application also provides options for Directory Look-Up and Find option.

我已经将源代码添加在附件中了,源代码中包含了Trie算法类库一个Console测试程序。Console测试程序会加载一些字符串(存储在Debug文件夹下的names.txt文件中)到Trie树上,并且可以在深度优先以及广度优先切换算法。

The class library can be further used to develop a web based phone directory. The data can also be stored on the client (it is too small) and the Trie can be implemented in JavaScript.

这个类库可以被进一步开发成为一个基于Web的电话目录,数据可以存储在客户端,然后使用JavaScript来实现Trie算法。

Happy Coding!

编程快乐!

原贴地址:http://www.codeproject.com/KB/recipes/PhoneDirectory.aspx

转载于:https://www.cnblogs.com/tedzhao/archive/2008/10/19/1314665.html

TRIE - Data Structure相关推荐

  1. leetcode 211. Add and Search Word - Data structure design Trie树

    题目链接 写一个数据结构, 支持两种操作. 加入一个字符串, 查找一个字符串是否存在.查找的时候, '.'可以代表任意一个字符. 显然是Trie树, 添加就是正常的添加, 查找的时候只要dfs查找就可 ...

  2. LeetCode Two Sum III - Data structure design

    原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...

  3. leetcode Add and Search Word - Data structure design

    我要在这里装个逼啦 class WordDictionary(object):def __init__(self):"""initialize your data str ...

  4. 牛客小白月赛11:Rinne Loves Data Structure

    Rinne Loves Data Structure 思路 我们插入的位置大概分了四种: 第一种 显然我们找到比当前插入的值的pre,也就是比当前节点大的最小值. 第二种 我们只要找到当前节点的suc ...

  5. HDU - 7072 Boring data structure problem 双端队列 + 思维

    传送门 文章目录 题意: 思路: 题意: 你需要实现如下四个操作 q≤1e7q\le1e7q≤1e7 思路: 做的时候想了个链表的思路让队友写了,懒. 看了题解感觉题解还是很妙的. 你需要快速插入一个 ...

  6. HDU - 6967 G I love data structure 线段树维护矩阵 + 细节

    传送门 文章目录 题意: 思路: 题意: 给你两个长度为nnn的数组a,ba,ba,b,你需要完成如下四种操作: 思路: 思路还是比较简单的,首先建一颗线段树,线段树中维护a,b,a2,b2,aba, ...

  7. 170. Two Sum III - Data structure design【easy】

    170. Two Sum III - Data structure design[easy] Design and implement a TwoSum class. It should suppor ...

  8. 【HDU - 4217 】Data Structure? (线段树求第k小数)

    题干: Data structure is one of the basic skills for Computer Science students, which is a particular w ...

  9. [数据结构与算法 DSA 林轩田] 1. Introduction to Data Structure and Algorithm

    目录 算法 1.什么是算法 2.Five Criteria of Algorithm(算法的五大原则) 3. Correctness Proof of Algorithm(算法正确性) 4. Effi ...

最新文章

  1. Gitlab CI(一)
  2. python练习_Python随笔31:Python基础编程练习题27~28
  3. python dataframe 如何去除缺失值
  4. 解决Android中无法搜索联系人的问题
  5. 适配器模式——类适配器模式,对象适配器模式
  6. CruiseControl中应用NCover和NCoverExplore
  7. Fragment基础讲解
  8. android shape 按钮背景_Android UI:XML文件配置按钮等背景方案
  9. linux 7自定义服务,CentOS 7.x设置自定义开机启动,添加自定义系统服务
  10. Java菜鸟教程怎么用_菜鸟教程 Java 学习笔记 (基础教程)
  11. FIR滤波器之Hilbert变换
  12. 网站优化 SEO概念
  13. EMC设计经典15问
  14. 更改计算机睡眠时间无法打开,win7怎么设置电脑睡眠时间 win7电脑睡眠后黑屏打不开...
  15. 十六进制转十进制(栈实现)
  16. WTL 绘制 圆角对话框 自绘对话框
  17. Android11(30)/Android10(29)分区存储-存储访问框架(SAF)
  18. 向用户发送短信验证码
  19. c语言中的中pred函数作用,C++ partition()和stable_partition()函数详解
  20. 如何从SAP Business One的HANA数据库中提取数据用于数据分析?

热门文章

  1. 2020年数学与计算机科学奖获得者,2020 数学与计算机科学奖 获奖人 —— 彭实戈 - 未来科学大奖...
  2. python 标准差_标准差python
  3. nginx重新加载php,如何使用nginx启动、停止和重新加载
  4. BZOJ-3110-K大数查询-ZJOI2013-暴力
  5. ICCV 2017 《Chained Cascade Network for Object Detection》论文笔记
  6. BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay)
  7. php 正则匹配字母和数字,正则匹配密码只能是数字和字母组合字符串功能【php与js实现】...
  8. golang适合做什么_什么八字适合做销售 适合做销售的八字特征
  9. 退格键删除input中光标指定的字符串_Linux中的vi 三种模式
  10. JDK1.8中的Stream详解