栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Trie树的两种JAVA实现方式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Trie树的两种JAVA实现方式

Trie树,又叫字典树,是一种用于快速检索查找字符串的树形数据结构
说白了就是把字符串树化,每个节点是一个字符,每个节点最多有字典长度个数的子节点(比如总共有26个小写字母,那每个节点最多就有26个子节点)

图中的Trie树中有三个字符串ap.ad.bd 根节点没有字符
Trie主要有两种实现方式 二维数组和树,按照LEETCODE208题的格式来实现

树
 class TrieNode{
       boolean isEnd;
       TrieNode[] arr=new TrieNode[26];

   }

创建节点,假设Trie中的字符串都是小写字母(26个),用一个TrieNode数组来表示这26个子节点,通过下标按照字母顺序来记录是哪个字母,a是0,b是1…

class Trie {
   class TrieNode{
       boolean isEnd;
       TrieNode[] arr=new TrieNode[26];

   }
   TrieNode root;

    public Trie() {
      root=new TrieNode();
    }
    
    public void insert(String word) {
        TrieNode node=root;
         for(int i=0;i
             int x=word.charAt(i)-'a';
             if(node.arr[x]==null) node.arr[x]=new TrieNode();
              node=node.arr[x];
         }
        node.isEnd=true;   
    }
    
    public boolean search(String word) {
         TrieNode node=root;
         for(int i=0;i
             int x=word.charAt(i)-'a';
             if(node.arr[x]==null) return false;
             node=node.arr[x];
         }         
          return node.isEnd;
    }
    
    public boolean startsWith(String prefix) {
             TrieNode node=root;
             for(int i=0;i
                 int x=prefix.charAt(i)-'a';
                 if(node.arr[x]==null) return false;
                 node=node.arr[x];
             }  
             return true;
    }
}
二维数组

通过二维数组实现比较抽象
如下图,其中:
index是一个编号,意思是字符插入的顺序,代表该字符是第index执行插入的,如果字符已经存在(在公共前缀里),则不会进行插入
count[i] 意思是编号是i的字符是几个字符串的结束点,如果count[i]==0说明他不是一个结束点
trie[p] [u]中存储的是编号,意思是当前这个字符(u号字符)的下一个字符的位置(也就是p)这个位置也就是trie的行号,比如trie[3][4]=5;意思就是e(a+4=e)的下一个字符是第6行的,具体是哪个字符要看u

class Trie {
    int N=100000;
    int[][] trie;
    int[] count;
    int index;

    public Trie() {
       trie=new int[N][26];
       count=new int[N];
       index=0;
    }
    
    public void insert(String word) {
         int p=0;
         for(int i=0;i
             int x=word.charAt(i)-'a';
             if(trie[p][x]==0) trie[p][x]=++index;
             p=trie[p][x];
         }
        count[p]++;

    }
    
    public boolean search(String word) {
          int p=0;
          for(int i=0;i
              int x=word.charAt(i)-'a';
              if(trie[p][x]==0) return false;
              p=trie[p][x];
          }
          return count[p]!=0;
    }
    
    public boolean startsWith(String prefix) {
          int p=0;
          for(int i=0;i
              int x=prefix.charAt(i)-'a';
              if(trie[p][x]==0) return false;
              p=trie[p][x];
          }
          return true;
    }
}

trie这个数组很抽象,做个测试,插入app.apple.banana.orange,数组为:

第一个插入的是app,index是1,2,3 在0,1,2行
第二个插入的是apple,这是又从第一行开始检索,因为apple的前缀app已经在数组中了,所以不会插入,直到走到 “l” 的时候,才会进行插入(此时p从3到4).
第三个插入的是banana,index此时已经到6了。。插入banana对应的是6,7,8,9,10,11。b在第0行,其余的在6,7,8,9,10行
第四个插入的是orange,与banana同理,o在第一行,其他的在对应的index-1行

具体是行中的第几个需要看u,也就是字母顺序

app:

apple:

banana:

orange:

总结:二维数组难理解 效率也不是很高 还是用tree吧

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1017514.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号