【问题标题】:Search Trie in O(N) in C在 C 中以 O(N) 搜索 Trie
【发布时间】:2014-10-06 01:38:43
【问题描述】:

您如何在 C 中在 O(n) 时间内遍历一个 trie。我想进行一个 for 循环循环,该循环遍历第 1 级,如果匹配一个字母,则搜索根链表,然后搜索该链表,但会给出我 n^2 次。有什么办法可以加快速度吗?

谢谢!

【问题讨论】:

  • 试试?树 ?哪一个?
  • 由于 OP 在标题和问题中都列出了它,我认为可以肯定地说 trie,因为它更具体地针对所讨论的树的类型。
  • @chouaib 我正在考虑使用 Trie!
  • 使用输入扫描中的下一个符号直接表索引,因为索引是最快的方法。唉,它也是最节省空间的低效,因为它要求每个节点中的子列表的大小等于符号集的基数。没有展示任何关于你的超级秘密 Trie 看起来像的内容(即你发布了没有代码),因此将它留给读者想象,这就是我的想象.这对空间利用率来说是可怕的,但它会毫无疑问地达到你想要的目标。

标签: c linked-list trie


【解决方案1】:

“O(n)”中使用的“n”是什么?如果 n 表示搜索字符串中的字符数,则可能会在 O(n) 时间内执行以下代码。

/* structure of Trie node */
struct trieNode {
   char *value;
   childNode children();
   int childCount;
}

/* structure for childnode in a Trie node. Whichi contains 'key' and pointer to child node */
struct childNode {
   char key;
   trieNode *node;
}


/* setup Trie and search string. (not real code) */
trieNode root=createTrinode(...) ; /* Setup Trie of your problem. */
char* searchString = inputSearchString(...); /* get string for search */

int i;
trieNode curNode;

curNode = root;
for i=0 to len(searchString)-1
{
    curNode = findChildren(curNode,searchString(i)); /* findChildren function returns childnode of first argument, whose key is equal to second argument.  (Code of findChildren is omitted) */
}

/* curNode is the traversed leaf node by  searchStrin */

for-loop 的索引是 0 到 n(searchString 的长度)-1,所以这段代码可能会执行 jn O(n) 时间。

此代码不考虑给定 Trie 中不包含 serach-string 的情况。

【讨论】:

    【解决方案2】:

    Trie 是一个非常有趣的数据结构,在其中你必须用时间复杂度来换取空间复杂度。

    但是你可以通过使用映射来降低空间复杂度,这对 O(1) 的查找非常有用,并且插入的复杂度也更低。

    这里是使用 hashmaps 的 Trie 实现:

        #include <iostream>
    #include <unordered_map>
    
    using namespace std;
    
    struct Trie
    {
        int isLeaf;
        unordered_map<char, Trie *> children;
    };
    
    struct Trie *getNewTrieNode()
    {
        Trie *Node = new Trie();
        Node->isLeaf = 0;
        return Node;
    }
    
    void insert(struct Trie *&head, char *str)
    {
        if (head == NULL)
            head = getNewTrieNode();
        struct Trie *curr = head;
        while (*str)
        {
            if (curr->children.find(*str) == curr->children.end())
                curr->children[*str] = getNewTrieNode();
            curr = curr->children[*str];
            str++;
        }
        curr->isLeaf = 1;
    }
    
    int search(struct Trie *head, char *str)
    {
    
        if (head == NULL)
            return 0;
    
        struct Trie *curr = head;
        while (*str)
        {
            curr = curr->children[*str];
            if (curr == NULL)
                return 0;
            str++;
        }
        return curr->isLeaf;
    }
    
    int havechildren(struct Trie *curr)
    {
        for (auto i : curr->children)
            if (i.second != NULL)
                return 1;
        return 0;
    }
    
    int deletion(struct Trie **curr, char *str)
    {
        if (*curr == NULL)
            return 0;
        if (*str)
        {
            if (curr != NULL && (*curr)->children.find(*str) != (*curr)->children.end() && deletion(&((*curr)->children[*str]), str + 1) && (*curr)->isLeaf == 0)
            {
                if (!havechildren(*curr))
                {
                    delete (*curr);
                    (*curr) = NULL;
                    return 1;
                }
                else
                    return 0;
            }
        }
        if (*str == '\0' && (*curr)->isLeaf)
        {
            if (!havechildren(*curr))
            {
                delete (*curr);
                (*curr) = NULL;
                return 1;
            }
            else
            {
                (*curr)->isLeaf = 0;
                return 0;
            }
        }
    }
    
    int main()
    {
        struct Trie *head = getNewTrieNode();
    
        insert(head, "hello");
        printf("%d ", search(head, "hello")); // print 1
    
        insert(head, "helloworld");
        printf("%d ", search(head, "helloworld")); // print 1
    
        printf("%d ", search(head, "helll")); // print 0 (Not present)
    
        insert(head, "hell");
        printf("%d ", search(head, "hell")); // print 1
    
        insert(head, "h");
        printf("%d \n", search(head, "h")); // print 1 + newline
    
        deletion(&head, "hello");
        printf("%d ", search(head, "hello"));      // print 0 (hello deleted)
        printf("%d ", search(head, "helloworld")); // print 1
        printf("%d \n", search(head, "hell"));     // print 1 + newline
    
        deletion(&head, "h");
        printf("%d ", search(head, "h"));           // print 0 (h deleted)
        printf("%d ", search(head, "hell"));        // print 1
        printf("%d\n", search(head, "helloworld")); // print 1 + newline
    
        deletion(&head, "helloworld");
        printf("%d ", search(head, "helloworld")); // print 0
        printf("%d ", search(head, "hell"));       // print 1
    
        deletion(&head, "hell");
        printf("%d\n", search(head, "hell")); // print 0 + newline
    
        if (head == NULL)
            printf("Trie empty!!\n"); // Trie is empty now
    
        printf("%d ", search(head, "hell")); // print 0
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-19
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      相关资源
      最近更新 更多