如何在C中O(n)时间遍历一个trie。我想做一个for循环循环,如果一个字母匹配则通过1级搜索根链表然后搜索该链表但会给出我n ^ 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;
}