字典树简单示例

字典树的基本功能是用来查询某个单词(前缀)在所有单词中出现次数的一种数据结构,它的插入和查询复杂度都为O(len),Len为单词(前缀)长度,但是它的空间复杂度却非常高,如果字符集是26个字母,那每个节点的度就有26个,典型的以空间换时间结构。
这题就是统计一组字符串中某前缀出现次数

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

#define MAX 26
#define LENTH 1000000
struct _Node{
        int nCount;
        struct _Node* next[MAX];
};
typedef struct _Node TrieNode;
TrieNode tn[LENTH];
int all=0;


//初始化
void init(TrieNode ** pRoot)
{
        *pRoot = NULL;

}
//创建新结点
TrieNode * createNode()
{
        int i;
        TrieNode * p;
        if(all < LENTH)p = &tn[all++];

        else return  NULL;
        p->nCount = 1;
        for(i = 0 ; i  < MAX ; ++i)
        {
            p->next[i] = NULL;
        }
        return p;

}
//插入
void insertNode(TrieNode **pRoot,char *s)
{
        TrieNode * p;
        if(!(p=*pRoot))
        {
           p=*pRoot=createNode();
        }
        int i,k;
        i = 0;
        while(s[i])
        {
           k = s[i]-'a';
           if(p->next[k])
                 p->next[k]->nCount++;
           else{
                p->next[k]=createNode();
           }
           p = p->next[k];
           ++i;
        }
}
//查找
int searchTrie(TrieNode ** pRoot, char *s)
{
        int i,k;
        TrieNode * p;
        if(!(p = *pRoot))return 0;
        i = 0;
        while(s[i])
        {
           k = s[i++]-'a';
           if(p->next[k])
           {
              p=p->next[k];
           }else{
             return 0;
           }
        }
        return p->nCount;
}
int main()
{
        printf("hello world\n");
        TrieNode * root;
        init(&root);
        char s[11];
        while(gets(s)&&s[0])
        {
           insertNode(&root,s);

        }
        printf("插入结束\n");
        while(gets(s))
        {
           printf("%d\n",searchTrie(&root,s));
        }
        return 0;
}

判断一组字符串中是否有一个字符串是另一个字符串的前缀(字典树第二类应用)。

我们只要在结点中添加一个nEndFlag成员变量即可。若nEndFlag == 1,说明该结点字符是某一字符串的结尾(假设为A),若在插入B字符串的过程中经过这一结点,则说明A是B的前缀;还有一种情况,当要插入最后一个字符c时,却发现p->next[c-'0']为真,则说明该字符串是一个前缀字符串,eg:先插入abcde,再插入abc这种情况

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

#define MAX 26
#define MAXLEN 1000000

struct _Node{
        int nEndFlag;
        struct _Node* next[MAX];
};
typedef struct _Node TrieNode;

TrieNode tn[MAXLEN];
int all = 0;
int nflag = 0;
void initTrie(TrieNode ** root)
{
        *root = NULL;
}
TrieNode * createNode()
{
        TrieNode *p;
        p = &tn[all++];
        p->nEndFlag = 0;
        int i ;
        for(i = 0;i < MAX ; ++i)
        {
           p->next[i] = NULL;
        }
        return p;
}
int  insertNode(TrieNode ** pRoot,char *s)
{
        TrieNode * p ;
        if(!(p = *pRoot))
        {
           p = *pRoot = createNode();
        }
        int i =0,k;
        while(s[i])
        {
           k = s[i++] - 'a';
           if(p->next[k])
           {
                if(p->next[k]->nEndFlag == 1 || s[i] == '\0')
                {
                     return 1;
                }
           }
           else
           {
                p->next[k] = createNode();
           }
           p = p->next[k];
        }
        p->nEndFlag = 1;
        return 0;
}
int main()
{
        printf("hello world\n");
        TrieNode * root;
        initTrie(&root);
        char s[11];
        int i, n;
        int flag = 0;
        scanf("%d",&n);
        getchar();
        printf("%d",n);
        for(i = 0;i < n; ++i)
        {
           gets(s);
           puts(s);
           printf("%d\n",i);
           if(flag == 0){
                flag = insertNode(&root,s);
           }
        }
        flag?printf("YES\n"):printf("NO\n");
        return 0;
}



                                                                      


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值