如何在Trie中打印所有单词?

时间:2012-12-03 14:50:29

标签: c++ data-structures trie

我正在尝试用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中的每个单词。

感谢您的帮助。

3 个答案:

答案 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);