字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。java
典型应用:用于统计,排序和保存大量的字符串(但不只限于字符串),因此常常被搜索引擎系统用于文本词频统计。node
优势:利用字符串的公共前缀来减小查询时间,最大限度地减小无谓的字符串比较,查询效率比哈希树高。ios
实现方法
搜索字典项目的方法为:
(1) 从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在某个结点处,关键词的全部字母已被取出,则读取附在该结点上的信息,即完成查找。
其余操做相似处理c++
插入字符串图解(例如”csdn“)
一、一开始为空树,指针节点为头节点,从头节点开始查找,是否有”c“这个节点。(头节点不储存数据)
二、不存在”c“这个节点,则在指针下添加子节点”c“。
三、此时将指针节点赋值为“c”,则在”c“中寻找下一个要添加的字符”s“,不存在,重复2步骤添加,如果存在,则直接将指针节点赋值为此节点便可。如此反复,直到全部的字符添加完毕。
四、最后将最后添加的节点的末节点值增长,表示以此为末节点的数量为1。
五、字符串”csdn“就添加完成了。同理,查询、删除等操做也是如此,从头节点开始,一个个搜寻。web
c++代码数组
#include<iostream> #include<cstdio> using namespace std; typedef struct Node node; struct Node{ int id;//标记是否为尾节点,同时统计数量 node *next[26]; Node(){ for(int i=0;i<26;i++){ next[i]=NULL; } id=0; } }*root=new Node(); int W; void insert(string str){//建表插入 int len=str.length(); int index=0; node* tail=root; for(int i=0;i<len;i++){ index=str[i]-'A'; if(tail->next[index]==NULL){ tail->next[index]=new Node(); } tail=tail->next[index]; } tail->id++; } bool contain(string str){ node *tail=root; for(int i=0;i<str.length();i++){ if(tail->next[str[i]-'A']!=NULL){ tail=tail->next[str[i]-'A']; }else{ return false; } } return tail->id>0; } int main(){ string te; cin>>W; for(int j=0;j<W;j++){ cin>>te; insert(te); } for(int k=0;k<10;k++){ string x; cin>>x; cout<<"HAVE "<<x<<" ? :"; if(contain(x)){ cout<<"Yes"; }else{ cout<<"No"; } cout<<endl; } }
java代码svg
import java.util.ArrayList; public class Trie{//字典树类 Node head=new Node(); class Node{//节点 char data;//节点数据 int Endnum=0;//以此为末节点的数量(表明有几个此单词) ArrayList<Node> childList=new ArrayList<>();//子节点,直接用数组,增长、删除、查找等效率会更高 Node(){} Node(char ch){ this.data=ch; } Node addchild(char data){ Node child=new Node(data); childList.add(child); return child; } void delete(){ this.Endnum--;//减少末节点标记 } Node isHave(char data){ for (Node node:childList){ if (node.data==data){ return node; } } return null; } } public void add(String str){ char[] chars=str.toCharArray(); Node node=head,temp=null; for (int i=0;i<chars.length;i++){ if ((temp=node.isHave(chars[i]))!=null){//寻找是否有此节点 node=temp; }else{ node=node.addchild(chars[i]);//新建节点,同时赋值 } } node.Endnum++;//将最后一个标记为终节点,说明有此字符串 } public void delete(String str){ char[] chars=str.toCharArray(); Node node=head,temp=null; for (int i=0;i<chars.length;i++){ temp=node.isHave(chars[i]); if (temp!=null){ node=temp; }else{ System.out.println("无此字符串"); return; } } node.delete();//取消最后一个标记 } public int isHave(String str){//返回0或-1表示无此字母 char[] chars=str.toCharArray(); Node node=head,temp=null; for (int i=0;i<chars.length;i++){ temp=node.isHave(chars[i]); if (temp==null){ return -1; }else{ node=temp; } } return node.Endnum; } }
操做演示this
public class Main { public static void main(String[] args) { Trie trie=new Trie(); trie.add("abc");//添加 trie.add("abc"); trie.add("abc"); trie.delete("abc");//删除 System.out.println(trie.isHave("abc"));//查找 } }
运行结果
搜索引擎
参考资料:字典树_百度百科spa