How to print all words in a Trie?

纵然是瞬间 提交于 2019-12-04 09:00:25

Here is a reasonably efficient version of Konrad Rudolph, without assuming data is a character. I also removed the O(n^2) total memory allocated in Konrad's version at the cost of using a std::string&. The idea is to pass down the prefix and modify it at each recursion, pushing characters onto the end and poping it afterwards, ends up being slightly more efficient than copying it madly.

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();
    }
  }
}

You don’t need your parent node, your code readily accommodates traversal via recursion. Pseudo-code:

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);
}

This is more or less valid C++. Just define print appropriately.

EDIT In response to Yakk’s comment and your clarification, here’s a version which doesn’t assume that data contains the current character (bad slip on my part!):

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]);
}

I’ll leave the more efficient implementation to Yakk’s answer.

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;
        }
    }
}

// Calling

char out[MAX_WORD_SIZE];
traversePrint(root,out,0);

I dont think isword is needed here. The existence of the pointer to children will be enough to traverse the trie for available words in the trie. to find a word, start from the root and look for the current character within the word during any recursive step.

struct trie {
  trie *children[ALPHABET_SIZE];
};


void traversal(trie *&t, string &str) {
    bool is_seen = false;
    for(int i = 0; i < ALPHABET_SIZE; i++) {
        if(t->children[i]) {
            if(!is_seen) {
               is_seen = true;
            }
            str.push_back(t[i]);
            traversal(t->children[i], str);
            str.pop_back();
        }
    }
    if(!is_seen) {
        cout << str << "\n";
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!