我正在尝试用C ++创建Trie
实现。我无法弄清楚如何打印Trie
中存储的所有单词。
这就是我实施TrieNode
。
struct TrieNode{
bool isWord;
int data; //Number of times Word Occured
TrieNode *Child[ALPHABET_SIZE]; //defined as 26
};
我知道我可以将pointer
存储到父节点,Depth-First搜索isWord==True
的所有节点,并递归打印这些节点中的每个单词。
但我想知道有没有办法在我Trie
的实施中打印TrieNode
中的每个单词。
感谢您的帮助。
答案 0 :(得分:10)
这是一个相当有效的Konrad Rudolph版本,不假设数据是一个字符。我还以使用std::string&
为代价删除了Konrad版本中分配的O(n ^ 2)总内存。这个想法是传递前缀并在每次递归时修改它,将字符推到最后然后弹出它,最后比疯狂复制它更有效。
void traverse(std::string& prefix, TrieNode const& node) {
if (node.isWord)
print(prefix);
for (char index = 0; index < ALPHABET_SIZE; ++index) {
char next = 'a'+index;
TrieNode const* pChild = node.Child[index];
if (pChild) {
prefix.push_back(next);
traverse(prefix, *pChild);
prefix.pop_back();
}
}
}
答案 1 :(得分:5)
您不需要父节点,您的代码可以通过递归轻松适应遍历。伪代码:
void traverse(string prefix, TrieNode const& n) {
prefix += static_cast<char>(n.data);
if (n.isWord)
print(prefix);
for (auto const next : n.Child)
if (next)
traverse(prefix, *next);
}
这或多或少是有效的C ++。只需恰当地定义print
。
编辑为了回应Yakk的评论和您的澄清,这里有一个版本,它不会假设data
包含当前字符(我的错误!):
void traverse(string const& prefix, TrieNode const& n) {
if (n.isWord)
print(prefix);
for (std::size_t i = 0; i < ALPHABET_SIZE; ++i)
if (n.child[i])
traverse(prefix + ('a' + i), *n.child[i]);
}
我会将更有效的实施留给Yakk的回答。
答案 2 :(得分:0)
void traversePrint(TrieNode* sr,char* out,int index)
{
if(sr!=NULL)
{
for(int i=0;i<SIZE;i++)
{
if(sr->child[i]!=NULL)
{
out[index] = 'a'+i;
traversePrint(sr->child[i],out,index+1);
}
}
if(sr->isEnd)
{
out[index]='\0';
cout << out << endl;
}
}
}
//致电
char out[MAX_WORD_SIZE];
traversePrint(root,out,0);