• Trie树的分析与实现


     字典树

           又称单词查找树,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    http://www.cnblogs.com/wxisme/p/4876980.html

  • 相关阅读:
    Install the Maven in your computer
    《李嘉诚全传》--孙良珠
    Crystal Reports 2008(水晶报表) 第一个报表
    《唤醒心中的巨人》--[美]安东尼·罗宾
    《写给女人》--[美]桃乐丝·卡耐基
    Crystal Reports 2008(水晶报表) JDBC连接mysql数据库
    Crystal Reports 2008(水晶报表) 启动时检查更新
    Crystal Reports 2008(水晶报表) 安装
    《百年孤独》--[哥伦比亚]加夫列尔·加西亚·马尔克斯
    《自己拯救自己》--[英]塞缪尔·斯迈尔斯
  • 原文地址:https://www.cnblogs.com/wxisme/p/4876197.html
Copyright © 2020-2023  润新知