【问题标题】:Insert data into a trie将数据插入到 trie 中
【发布时间】:2017-12-02 13:48:24
【问题描述】:

所以我正在尝试将 insert 数据放入 trie 中,并且我的代码工作正常。但是后来我稍微改变了我的插入函数,它不再起作用并且还导致内存泄漏。对我来说,insert 的两个版本都做同样的事情,但显然它们不是。有人可以向我解释为什么吗?提前致谢。

这是有效的代码

#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 26

#define hash(c) (tolower(c) - (int)'a')

typedef struct node{
    bool endWord;
    struct node* children[SIZE];
} node;

void freeTrie(node* root){

    if(root == NULL) return;

    for (size_t i = 0; i < SIZE; i++) {
        freeTrie(root->children[i]);
    }

    free(root);
}

node* newNode(){
    node* new = NULL;

    new = (node*) malloc(sizeof(node));

    if(new != NULL){

        new->endWord = false;

        for(int i = 0; i < SIZE; i++)
            new->children[i] = NULL;
    }

    return new;
}

void insert(node* root, const char* data){

    node* temp = root;

    for (size_t i = 0, len = strlen(data); i < len; i++) {

        int index = hash(data[i]);

        if(temp->children[index] == NULL){

            temp->children[index] = newNode();

            if (temp->children[index] /*still*/ == NULL){
                printf("Something went wrong\n");
                return;
            }
        }

        temp = temp->children[index];
    }
    temp->endWord = true;
}

bool search(node* root, const char* data){

    node* temp = root;

    for (size_t i = 0, len = strlen(data); i < len; i++) {

        int index = hash(data[i]);

        temp = temp->children[index];

        if (temp == NULL){
            printf("search end here\n");
            return false;
        }
    }

    return (temp != NULL && temp->endWord);
}

int main() {

    char data[][8] = {"fox", "foo", "dog", "do"};

    node* root = newNode();

    if(root == NULL){
        printf("Something went wrong\n");
        return 1;
    }

    for (size_t i = 0, dataSize = sizeof(data)/sizeof(data[0]); i < dataSize; i++) {
        insert(root, data[i]);
    }

    printf("Check: \n");

    char output[][32] = {"not found", "found"};

    // char s[5];
    // fscanf(stdin, "%s", s);

    printf("%s\n", output[search(root, "fox")]);

    freeTrie(root);

    printf("Done\n");

    return 0;
}

这是让我困惑的insert

void insert(node* root, const char* data){

    node* temp = root;

    for (size_t i = 0, len = strlen(data); i < len; i++) {

        int index = hash(data[i]);

        temp = temp->children[index];

        if(temp == NULL){

            temp = newNode();

            if (temp /*still*/ == NULL){
                printf("Something went wrong\n");
                return;
            }
        }
    }

    temp->endWord = true;
}

PS:我这样做是针对 CS50x 课程的问题集,其中我必须将包含 143091 个单词(按字母顺序)的字典加载到我的 trie 中。当工作人员仅用 0.02 秒和 0.01 秒完成相同的工作时,我的程序加载大约需要 0.1 秒,卸载大约需要 0.06 秒。我不允许查看员工的源代码,但我猜他们使用 trie 存储数据。如何改进我的代码以获得更快的运行时间?如果我将数据存储在数组中然后进行二进制搜索,它会运行得更快吗?

【问题讨论】:

    标签: c data-structures trie cs50


    【解决方案1】:

    当你写作时

    temp = temp->children[index];
    

    您将包含在temp-&gt;children[index](我称之为A)中的值复制到一个名为temp 的完全独立变量中。当您稍后修改temp 时,您只修改temp,而不是A。也就是说,所有新节点都不会插入到 trie 中。

    【讨论】:

    • 我认为temp-&gt;children[index] 是一个指针,然后A 是一个内存块(或NULL)的地址,对吗?所以在temp = temp-&gt;children[index] temp 指向A 寻址的位置之后。我是不是误会了什么?
    • @Lone temp 确实指向A 寻址的位置。但是,稍后您检查temp 是否为NULL,如果是,则创建一个新节点并使temp 指向新节点,而A 仍指向NULL。在第一个版本的代码中,你修改了A
    • 哦,我明白了。这确实为我澄清了事情。太感谢了。我希望我能给你一个赞成票,但我不能。顺便说一句,我能做些什么来优化我的代码吗?
    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 2021-11-11
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多