实现插入和查询
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdexcept>
using namespace std;
struct Node
{
bool isWord;//判断当前字母是否为单词的最后一个字母标识
Node *next[26];//26叉
Node()
{
isWord = false;
for (int i = 0; i != 26; ++i)
{
next[i] = NULL;//清空26叉
}
}
};
class DicTree
{
public:
Node *root;//根节点
DicTree()
{
root = NULL;//在构造函数中初始化
}
void Insert(string str)
{
if (!root)
{
root = new Node;//如果root现在不空,需要重新开辟一个根节点
}
Node *head = root;//根节点不能变,找一个新的指针指向根节点方便操作
for (long int i = 0; i != str.length(); ++i)
{
int num = str[i] - 'a';//获取当前字母应该存储的位置
if (head->next[num] == NULL)
{
head->next[num] = new Node;
}
head = head->next[num];
}
head->isWord = true;
}
bool Search(string str)
{
Node *head = root;
for (long int i = 0; i != str.length(); ++i)
{
int num = str[i] - 'a';
if (head->next[num] == NULL)
{
return false;
}
else
{
head = head->next[num];
}
}
return head->isWord;
}
};
int main(int argc, const char * argv[])
{
string inp1;
DicTree A;
while (cin >> inp1, inp1 != "quit")
{
A.Insert(inp1);
}
cout << "-----------------------------" << endl;
cout << "input end" << endl;
cout << "-----------------------------" << endl;
string inp2;
while (cin >> inp2, inp2 != "quit")
{
bool res = A.Search(inp2);
cout << res << endl;
}
system("pause");
return 0;
}
完整版实现
#include <queue>
#include <iostream>
using namespace std;
const int maxs = 26;
struct TrieTreeNode
{
char val;
bool isEnd;
int childCnt;
int prefixCnt;
TrieTreeNode *child[maxs];
TrieTreeNode(char _val)
:val(_val), isEnd(false), childCnt(0), prefixCnt(0)
{
memset(child, NULL, sizeof(child));//not 26!!
}
};
void Insert(TrieTreeNode * root, const char *word)
{
TrieTreeNode * p = root;
for (int i = 0; i < strlen(word); i++)
{
if (p->child[word[i] - 'a'] == NULL)
{
p->child[word[i] - 'a'] = new TrieTreeNode(word[i]);
p->childCnt++;
}
p->child[word[i] - 'a']->prefixCnt++;
p = p->child[word[i] - 'a'];
}
p->isEnd = true;
}
bool find(TrieTreeNode * root, const char * word)
{
TrieTreeNode * p = root;
int len = strlen(word);
for (int i = 0; i < len; i++)
{
int c = word[i] - 'a';
if (p->child[c] == NULL)
{
return false;
}
p = p->child[c];
}
return p->isEnd;
}
void levelOrderTraverse(TrieTreeNode * root)
{
if (root == NULL)
return;
queue<TrieTreeNode *> q;
q.push(root);
while (!q.empty())
{
TrieTreeNode *p = q.front();
cout << p->val << "(" << p->childCnt << ")";
for (int i = 0; i < maxs; i++)
{
if (p->child[i] != NULL)
{
q.push(p->child[i]);
}
}
q.pop();
}
cout << endl;
}
void preOrderTraverse(TrieTreeNode * treeNode)
{
if (treeNode != NULL)
{
cout << treeNode->val << "(" << treeNode->childCnt << ")";
for (int i = 0; i < maxs; i++)
{
preOrderTraverse(treeNode->child[i]);
}
}
}
void PostOrderTraverse(TrieTreeNode * treeNode)
{
if (treeNode != NULL)
{
for (int i = 0; i < maxs; i++)
{
PostOrderTraverse(treeNode->child[i]);
}
cout << treeNode->val << "(" << treeNode->childCnt << ")";
}
}
void makeEmpty(TrieTreeNode * root)
{
if (root != NULL)
{
for (int i = 0; i < 26; i++)
{
makeEmpty(root->child[i]);
}
delete root;
}
root = NULL;
}
void buildTrieTree(TrieTreeNode * root, const char* words[], int n)
{
for (int i = 0; i < n; i++)
{
Insert(root, words[i]);
}
}
bool Remove(TrieTreeNode * root, const char *word, int pos, int n)
{
if (pos == n)
{
root->isEnd = false;
return root->childCnt;
}
if (root->child[word[pos] - 'a'] == NULL)
return false;
if (Remove(root->child[word[pos] - 'a'], word, pos + 1, n))
{
delete root->child[word[pos] - 'a'];
root->child[word[pos] - 'a'] = NULL;
root->prefixCnt--;
if (--root->childCnt == 0 && root->isEnd == false)
{
return true;
}
}
return false;
}
int countWordsWithPrefix(TrieTreeNode * root, const char *prefix)
{
TrieTreeNode *p = root;
for (int i = 0; i < strlen(prefix); i++)
{
if (p->child[prefix[i] - 'a'] == NULL)
{
return 0;
}
p = p->child[prefix[i] - 'a'];
}
return p->prefixCnt;
}
int main()
{
TrieTreeNode *root = new TrieTreeNode('\0');
const char *words[] = { "abc", "ad", "ef" };
buildTrieTree(root, words, sizeof(words) / sizeof(words[0]));
levelOrderTraverse(root);
cout << '\n';
preOrderTraverse(root);
cout << '\n';
PostOrderTraverse(root);
cout << "\n";
if (find(root, "ef"))
cout << "ef found" << endl;
else
cout << "ef not found" << endl;
Insert(root, "e");
levelOrderTraverse(root);
Remove(root, "ef", 0, strlen("ef"));
levelOrderTraverse(root);
Remove(root, "e", 0, strlen("e"));
levelOrderTraverse(root);
cout << countWordsWithPrefix(root, "a") << endl;
Remove(root, "ad", 0, strlen("ad"));
cout << countWordsWithPrefix(root, "a") << endl;
makeEmpty(root);
system("pause");
return 0;
}