Trie树|字典树(字符串排序)

来源:互联网 发布:淘宝商城半身裙 编辑:程序博客网 时间:2024/05/16 01:33

有时,我们会碰到对字符串的排序,若采用一些经典的排序算法,则时间复杂度一般为O(n*lgn),但若采用Trie树,则时间复杂度仅为O(n)。

Trie树又名字典树,从字面意思即可理解,这种树的结构像英文字典一样,相邻的单词一般前缀相同,之所以时间复杂度低,是因为其采用了以空间换取时间的策略。

下图为一个针对字符串排序的Trie树(我们假设在这里字符串都是小写字母),每个结点有26个分支,每个分支代表一个字母,结点存放的是从root节点到达此结点的路经上的字符组成的字符串。

将每个字符串插入到trie树中,到达特定的结尾节点时,在这个节点上进行标记,如插入"afb",第一个字母为a,沿着a往下,然后第二个字母为f,沿着f往下,第三个为b,沿着b往下,由于字符串最后一个字符为'\0',因而结束,不再往下了,然后在这个节点上标记afb.count++,即其个数增加1.

之后,通过前序遍历此树,即可得到字符串从小到大的顺序。(图取自网络)


数据结构如下:

[java] view plaincopy
  1. package com.trie;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. /** 
  6.  * @author silence 
  7.  * @since 2013/7/2 
  8.  * */  
  9. public class Node {  
  10.    boolean isWord = false;  
  11.    Node[] child = new Node[26];//0-25:a:b  
  12.    List<String> pos = new ArrayList<String>();  
  13. }  
实现代码:

[java] view plaincopy
  1. package com.trie;  
  2. /** 
  3.  * @author silence 
  4.  * @since 2013/7/2 
  5.  * */  
  6. public class Trie {  
  7.     private Node root;  
  8.     Trie(){  
  9.         root = new Node();  
  10.     }  
  11.     public void addWord(String word,String pos){  
  12.         int len = word.length();  
  13.         Node s = root;  
  14.         for(int i =0;i<len;i++){  
  15.             int ch = word.charAt(i)-97;//c2 h7  
  16.             if(s.child[ch] !=null){//有节点了  
  17.                 s = s.child[ch];//后移  
  18.                   
  19.             }else{//没节点  
  20.              Node child = new Node();  
  21.               if(i==len-1){//最后一个字符  
  22.                  child.isWord = true;  
  23.                  child.pos.add(pos);  
  24.               }  
  25.               s.child[ch] = child;//挂上节点  
  26.               s = child;//后移  
  27.             }  
  28.         }  
  29.     }  
  30.     public void findWord(String word){  
  31.         int len = word.length();  
  32.         Node s = root;  
  33.         for(int i =0;i<len;i++){  
  34.             int ch = word.charAt(i)-97;  
  35.             if(s.child[ch]!=null){//节点存在  
  36.                 s = s.child[ch];//后移  
  37.                 if(i == len -1){  
  38.                     for(String pos :s.pos){  
  39.                         System.out.println(pos);  
  40.                     }  
  41.                 }  
  42.                   
  43.             }else{  
  44.                 System.out.println("不存在这个单词");  
  45.                 return ;  
  46.             }  
  47.               
  48.         }  
  49.     }  
  50.       
  51.     public static void main(String[] args) {  
  52.         Trie trie = new Trie();  
  53.         trie.addWord("silence""1");  
  54.         trie.addWord("hello""2");  
  55.         trie.addWord("word""3");  
  56.           
  57.         trie.findWord("silence");  
  58.           
  59.     }  
  60.   

0 0
原创粉丝点击