尝试执行中的以下语句有什么作用

时间:2016-07-27 01:37:41

标签: c++ data-structures

我一直在尝试实现插入trie数据结构的C ++实现,通过一个博客,其中有一些我无法理解的事情http://theoryofprogramming.com/2015/01/16/trie-tree-implementation/

#define ALPHABETS 26
#define CASE 'a'
#define MAX_WORD_SIZE 25
using namespace std;

struct Node
  {
   struct Node * parent;
   struct Node * children[ALPHABETS];
   vector<int> occurrences;
  };

  // Inserts a word 'text' into the Trie Tree
  // 'trieTree' and marks it's occurence as 'index'.

  void InsertWord(struct Node * trieTree, char  word[], int index)  
   {
   struct Node * traverse = trieTree;
   while (*word != '\0') { // Until there is something to process
    if (traverse->children[*word - CASE] == NULL) {

        // There is no node in 'trieTree' corresponding to this alphabet

        // Allocate using calloc(), so that components are initialised
      traverse->children[*word - CASE] = (struct Node *) calloc(1,  sizeof(struct Node));
        traverse->children[*word - CASE]->parent = traverse;  // Assigning parent
    }

    traverse = traverse->children[*word - CASE];
    ++word; // The next alphabet
}

  traverse->occurrences.push_back(index);      // Mark the occurence of the word
}

// Prints the 'trieTree' in a Pre-Order or a DFS manner
// which automatically results in a Lexicographical Order
void LexicographicalPrint(struct Node * trieTree, vector<char> word)
  {
  int i;
  bool noChild = true;
  if (trieTree->occurrences.size() != 0) {
    // Condition trie_tree->occurrences.size() != 0,
    // is a neccessary and sufficient condition to
    // tell if a node is associated with a word or not
    vector<char>::iterator charItr = word.begin();
    while (charItr != word.end()) {
        printf("%c", *charItr);
        ++charItr;
    }
    printf(" -> @ index -> ");

    vector<int>::iterator counter = trieTree->occurrences.begin();
    // This is to print the occurences of the word

    while (counter != trieTree->occurrences.end()) {
        printf("%d, ", *counter);
        ++counter;
    }

    printf("\n");
 }

 for (i = 0; i < ALPHABETS; ++i) {
    if (trieTree->children[i] != NULL) {
        noChild = false;
        word.push_back(CASE + i);   // Select a child

        // and explore everything associated with the cild
        LexicographicalPrint(trieTree->children[i], word);
        word.pop_back();
        // Remove the alphabet as we dealt
        // everything associated with it
     }
 }

  word.pop_back();
}

int main()
  {
   int n, i;
   vector<char> printUtil;       // Utility variable to print tree
   // Creating the Trie Tree using calloc
   // so that the components are initialised
   struct Node * trieTree = (struct Node *) calloc(1, sizeof(struct   Node));
  char word[MAX_WORD_SIZE];
  printf("Enter the number of words-\n");
  scanf("%d", &n);
  for (i = 1; i <= n; ++i) {
    scanf("%s", word);
    InsertWord(trieTree, word, i);
  }

  printf("\n");   // Just to make the output more readable
  LexicographicalPrint(trieTree, printUtil);

 return 0;
}

我无法理解insertword中的这句话:

     if (traverse->children[*word - CASE] == NULL)


另外,因为我们已经在main函数中将所有元素初始化为1,那么我们如何才能为null?

1 个答案:

答案 0 :(得分:0)

函数InsertWord()动态地将新单词添加到trie中,并且在此过程中,只要该单词的前缀与已在trie中添加的另一个单词的前缀不匹配,就会创建新节点。

这正是您的生产线正在测试的内容。从我所看到的,traverse是指向该单词前缀的当前节点的指针。 *word是前缀后单词中的下一个字符。如果对应于该单词的当前k - 前缀的节点没有子节点(指针为NULL)且标签对应于下一个字符,则表示我们必须为其分配新节点下一个k+1 - 单词的前缀。