字典树又称为前缀树或Trie树,是处理字符串常见的数据结构。
本文数据结构严格采用下面图示的结构进行编码,其中节点(圆圈内)内的数字左右分别表示{经过此节点的串数,此节点作为终结点的串数}。
所以将下图的字符串从左到又依次列出为:
{a、a、ae、atfh、by、ca、cag、caf}
结构源码:
/*
@Author:zhaojianli
@Data:2019/12/11
m_referCount:how many character string share this node.
m_end:how many character string end up at this point.
*/
struct TreeNode
{
int m_referCount;
int m_end;
std::map<char, TreeNode *> m_path;
TreeNode()
{
m_referCount = 1;
m_end = 0;
}
};
class TrieTree
{
public:
TrieTree()
{
m_root = new TreeNode();
assert(m_root != NULL);
}
bool insert(string s)
{
TreeNode* tmpNode = m_root;
std::map<char, TreeNode *>::iterator it;
for (int i = 0; i < s.length(); i++) {
if ((it = tmpNode->m_path.find(s[i])) == tmpNode->m_path.end()) {
TreeNode *node = new TreeNode;
if (!node) {
//这里需要做异常安全的处理
return false;
}
tmpNode->m_path.insert(std::make_pair(s[i], node));
tmpNode = node;
continue;
}
tmpNode = it->second;
tmpNode->m_referCount++;
}
tmpNode->m_end++;
return true;
}
bool search(std::string s)
{
TreeNode* tmpNode = m_root;
std::map<char, TreeNode*>::iterator it;
for (int i = 0; i < s.length(); i++) {
if ((it = tmpNode->m_path.find(s[i])) == tmpNode->m_path.end()) {
return false;
}
tmpNode = it->second;
}
return tmpNode->m_end > 0 ? true : false;
}
private:
TreeNode* m_root;
};