Trie树分析及其查询的实现

     Trie树是在查询问题中以空间换取时间的做法,时间复杂度为O(n),所以存在空间的大量消耗。

     本文Trie树的应用便是查询某个词缀在字典中出现的频率。

     Trie树的性质本文总结如下:

     1:根节点不存储任何字符;

     2:以某一个字符串结束标志节点为止,根节点至该节点所构成的路径内所有节点字符顺序构成一个字符串

     3:节点的所有子节点应包含不同的字符

     本文Trie树创建及查询:

      1:为方便查询词缀出现频率,在每一个节点中包含以根节点至该节点所构成词缀的出现次数(及完成子节点创建或不为NULL及重复字符串);

      2:节点中应包含字符串结束标志,在本文中使用true,false判断,亦可为根加显现的表示,可定义颜色字符串值(white/black)表示

      3:在本文中重复单词也算不同单词计算频率(做过的一道ACM题中出现,所以本文中代码也将重复单词作为不同单词处理,当然在实际应用中,为避免重复单词的插入,在插入之前可进行查询操作,避免重复插入)

     问题描述如下:

      输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组 成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示一个询问。
  输出:
     对于每一个询问,输出一个整数Ans,表示词典中给出的字符串为前缀的单词的个数。

      本文查询思路:

      接收到查询词缀,从根节点开始,循环查询,若在Trie树中不存在该词缀,返回0,若有,继续查询下一字符,直至词缀结束,返回此时所在节点的统计频率值。

      简单实现代码如下:

     

#include <stdio.h>
#include <stdlib.h>
#define false 0
#define true 1
typedef struct Trie_node{

    int count;
    struct  Trie_node* Trie_node_next[26];
    int IsWord;
} TrieNode, *Trie;

Trie  Trie_Create()
{
    Trie Trie_new=(Trie)malloc(sizeof(TrieNode));
    Trie_new->count=0;
    Trie_new->IsWord=false;
    int i;
    for(i=0;i<26;i++)
         Trie_new->Trie_node_next[i]=NULL;
    return Trie_new;
}
void  Trie_Insert(Trie root,char* word)
{
    Trie node=root;
    char *p=word;
    int id;
    while(*p)
    {
        id=*p-'a';
        if(node->Trie_node_next[id]==NULL)
            {
                node->Trie_node_next[id]=Trie_Create();
            }
            node=node->Trie_node_next[id];
            node->count+=1;
            ++p;
    }
    node->IsWord=true;

}
int  Trie_Search(Trie root, char* word)
{
    Trie node=root;
    char *p=word;
    int id;
    while(*p)
    {
        id=*p-'a';
        if(node->Trie_node_next[id]==NULL)
            return 0;
        node=node->Trie_node_next[id];
        ++p;
    }
    return node->count;
}
int  main()
{
        Trie Root=Trie_Create();
        int m,n,i;
        char word[10000],search[10000];
        int count;
        scanf("%d",&m);
        for(i=0;i<m;i++)
        {
            scanf("%s",word);
            Trie_Insert(Root,word);
        }
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%s",search);
            count=Trie_Search(Root,search);
            printf("%d\n",count);
        }

  return 0;
}
程序运行结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值