关闭

字典树简单示例

标签: structnull数据结构c
490人阅读 评论(0) 收藏 举报
分类:
字典树的基本功能是用来查询某个单词(前缀)在所有单词中出现次数的一种数据结构,它的插入和查询复杂度都为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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:570405次
    • 积分:6999
    • 等级:
    • 排名:第3486名
    • 原创:144篇
    • 转载:33篇
    • 译文:0篇
    • 评论:61条
    最新评论