在C中搜索O(N)中的Trie

时间:2014-10-06 01:38:43

标签: c linked-list trie

如何在C中O(n)时间遍历一个trie。我想做一个for循环循环,如果一个字母匹配则通过1级搜索根链表然后搜索该链表但会给出我n ^ 2次。有没有办法让我加快速度?

谢谢!

2 个答案:

答案 0 :(得分:0)

什么是" n"用于" O(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循环的索引是0到n(searchString的长度)-1,所以这段代码可以执行jn O(n)时间。

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

答案 1 :(得分:0)

Trie是一个非常有趣的数据结构,您必须在空间结构与时间复杂度之间进行权衡。

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

这里是使用哈希图实现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;
}