Trie树简介

488 阅读1分钟

一、介绍

trie树一般读作/ˈtraɪ/ "try"树,又称“字典树”或”前缀树“,“单词查找树”或“键树”,可以应用于搜索提示,当输入一个搜索关键字,可以根据前缀返回最相似的或者完全匹配的结果。 其他的应用有:字符串检索、词频统计、字符串排序、前缀匹配等。

二、实现

trie树,顾名思义是一种树形的结构,那么,我们就先来看一下组成trie树的树节点应该如何定义:

    class TrieNode {
        public int path;//这个节点所在字符路径上,有多少个单词用到了当前的节点
	public int end;// 有多少单词是以当前节点为结尾的
	public TrieNode[] nexts;// 下一层级的节点引用
	public TrieNode() {
	    path = 0;
	    end = 0;
	    nexts = new TrieNode[26];
	}
    }

一个完整的trie结构,有几个基本的操作api,我们逐一了解他们的作用:

public class Trie {
    private TrieNode root;

    public Trie() {
	root = new TrieNode();
    }
    // 插入单词到trie结构中
    public void insert(String word) {
	if (word == null) {
		return;
	}
	char[] chs = word.toCharArray();
	TrieNode node = root;
	int index;
	for (int i = 0; i < chs.length; i++) {
	    index = chs[i] - 'a';
	    if (node.nexts[index] == null) {
		node.nexts[index] = new TrieNode();
	    }
	    node = node.nexts[index];
	    node.path++;
	}
	node.end++;
    }
    
    // 查询单词是否在结构中存在
    public int search(String word) {
	if (word == null) {
	    return 0;
	}
	char[] chs = word.toCharArray();
	TrieNode node = root;
	int index = 0;
	for (int i = 0; i < chs.length; i++) {
	    index = chs[i] - 'a';
	    if (node.nexts[index] == null) {
		return 0;
	    }
	    node = node.nexts[index];
        }
	return node.end;
    }

    // 返回以pre做为前缀的单词的数量
    public int prefix(String pre) {
	if (pre == null) {
	    return 0;
	}
	char[] chs = pre.toCharArray();
	TrieNode node = root;
	int index = 0;
	for (int i = 0; i < chs.length; i++) {
	    index = chs[i] - 'a';
	    if (node.nexts[index] == null) {
		return 0;
	    }
	    node = node.nexts[index];
	}
	return node.path;
    }
    
    // 在结构中删除一个单词
    public void delete(String word) {
	if (search(word) != 0) {
	    char[] chs = word.toCharArray();
	    TrieNode node = root;
	    int index = 0;
	    for (int i = 0; i < chs.length; i++) {
		index = chs[i] - 'a';
		if (--node.nexts[index].path == 0) {
		    node.nexts[index] = null;
		    return;
		}
		node = node.nexts[index];
	    }
	    node.end--;
	}
    }
}