Java数据结构---Trie(字典树/前缀树)

1. Trie简介

前缀树是一种树形结构,在百度中查找一个单词,通常搜索前几个字母,百度就会自动提示后面的字母,即搜索提示,这是前缀树的一个最典型的应用。

2. 该数据结构的节点的构建

前缀树的结点包含属性isWord和指向孩子节点的指针children,它是一个数组。 完整的定义:

class TrieNode {
          
   
	// 该节点的属性---isWord,它是一个标签,用来表示是否是一个完整的单词
	boolean isWord;
	// 定义该节点的孩子节点,用一个长度为26的TrieNode[]数组来存储指向下一个孩子节点的指针
	TrieNode[] children;
	
public TrieNode {
          
   
	// 默认isWord标签为false
	isWord = false;
	// 默认孩子节点有26个(英文字母有26个),用一个长度为26的TrieNode[]数组来存储孩子节点的指针
	children = new TrieNode[26];
	}
}

可以简写成如下形式:

class TrieNode {
          
   
	boolean isWord;	
	TrieNode[] children = new TrieNode[26];
}

3. 前缀树的构建

// 定义前缀树的节点
class TrieNode {
          
   
	boolean isWord;								
	TrieNode[] children = new TrieNode[26];		
}
// 定义前缀树
class Trie {
          
   
    TrieNode root; 
    public Trie() {
          
   
    	// 构造一个空的节点作为根节点
        root = new TrieNode();
    }

4. 基础操作(增、查)

  1. 增 insert()
public void insert(String word) {
          
   
    TrieNode cur = root; 
    for (int i = 0; i < word.length(); i++) {
          
   
    // c为要保存字符的ASCII码值
    int c = word.charAt(i) - a; 
	// 如果当前节点的值为c的孩子节点不存在,则新建该孩子节点并指向它
	if (cur.children[c] == null) {
          
   
		cur.children[c] = new TrieNode();
	}
	// 如果当前节点的值为c的孩子节点存在,则cur指向该孩子节点
    cur = cur.children[c];
    }
    // 当所有节点都遍历完成,将当前节点,即最后一个节点的标识符isWord置为true,表示从根节点遍历到该节点的字母组成了一个单词
    cur.isWord = true;
}
  1. 完整查找 search():给定一个完整的单词,在前缀树中查找它是否存在 思路:如果在遍历过程中发现字母有缺失(cur.children[c] == null),即下一个字母查找为null,则返回false,表示前缀树种不存在这个单词。如果遍历完成,就要判断此时cur是否为单词末尾:如果是,返回true;如果不是,说明word仅仅是一个前缀,并不完整,返回false
public boolean search(String word){
          
   
	TrieNode cur = root;
	for(int i = 0;i < word.length(); i++){
          
   
		int c = word.charAt(i)-a;
		if(cur.children[c] == null) return false;
		cur = cur.children[c];
	}
	return cur.isWord;
}
  1. 按前缀查找 startsWith() 思路:与完整查找类似,区别在于不需要判断最后一个节点是否是isWord
public boolean search(String word){
          
   
	TrieNode cur = root;
	for(int i = 0;i < word.length(); i++){
          
   
		int c = word.charAt(i)-a;
		if(cur.children[c] == null) return false;
		cur = cur.children[c];
	}
	return true;
}

5. 练习

经验分享 程序员 微信小程序 职场和发展