前缀树需要实现3个函数:

  • insert:往前缀树中插入单词
  • search:查找前缀树中是否存在XX单词
  • startwith:查找前缀树中是否存在XX前缀。

前缀树的数据结构为26叉树,该数据结构TrieNode如下:

  • bool isWord;
  • TrieNode* children[26]; (初始化为nullptr)

如果插入字符,则对应的char位置的指针从nullptr变成实际的TrieNode*。

insert函数步骤:

  • 1 遍历输入字符串的每一个字符,进入root的children数组查找是否为nullptr,如果否则创建一个TrieNode。
  • 2 设置字符串遍历结束后的TrieNode节点的isWord为True。

search函数步骤:

  • 1 遍历输入字符串的每一个字符,进入root的children数组查找是否为nullptr,如果是,直接返回false,如果否,则继续遍历。
  • 2 查看字符串遍历结束后的TrieNode节点的isWord是否为True。

startWith函数步骤:

  • 1 遍历输入字符串的每一个字符,进入root的children数组查找是否为nullptr,如果是,直接返回false,如果否,则继续遍历。
  • 2 能到字符串遍历结束后的节点,则返回true。
class TrieNode {
	public:
		bool isWord;
		TrieNode *children[26];
		TrieNode() {
			isWord = false;
			memset(children, 0, sizeof(children));
		}
};

class Trie {
	public:
		TrieNode *root;
		Trie() {
			root = new TrieNode();
		}

		bool insert(const string &word) {
			TrieNode *cur = root;
			for (int i = 0; i < word.size(); i++) { int c = word[i] - 'a'; if (cur->children[c] == nullptr) {
					cur->children[c] = new TrieNode();
				}
				cur = cur->children[c];
			}
			cur->isWord = true;
		}

		bool search(const string &word) {
			TrieNode *cur = root;
			for (int i = 0; i < word.size(); i++) { int c = word[i] - 'a'; if (cur->children[c] == nullptr) {
					return false;
				}
				cur = cur->children[c];
			}
			return cur->isWord;
		}

		bool startWith(const string &word) {
			TrieNode *cur = root;
			for (int i = 0; i < word.size(); i++) { int c = word[i] - 'a'; if (cur->children[c] == nullptr) {
					return false;
				}
				cur = cur->children[c];
			}
			return true;
		}
};