首页 > 代码库 > 字典树的简单实现

字典树的简单实现

Trie树,又称为字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树数据结构。

用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。

Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

它有3个基本性质:
1、根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2、从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

3、每个节点的所有子节点包含的字符都不相同。

搜索字典项目的方法为:

(1) 从根结点开始一次搜索;

(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;

(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。
其他操作类似处理.
/*
功能描述:实现trie树的创建、插入、查询
说明:
     对统计对象,要求符合正则"[a-z]*"的格式的单词
     若考虑大写,标点和空白字符(空格.TAB.回车换行符),
     可修改next数组大小,最多255可包含所有字符
*/
#include<stdio.h>
#include <stdlib.h>
#include<string.h>

#define MAX_CHILD 26 //此函数只考虑26个英文字母的情况


typedef struct Tree
{
    int count;         //用来标记该节点是个可以形成一个单词,如果count!=0,则从根节点到该节点的路径可以形成一个单词
    struct Tree *child[MAX_CHILD];
} Node,*Trie_node;
/*
child是表示每层有多少种类的数,如果只是小写字母,则26即可,若改为大小写字母,则是52,若再加上数字,
     则是62了,这里根据题意来确定。
count可以表示一个字典树到此有多少相同前缀的数目,这里根据需要应当学会自由变化。
*/

Node* CreateTrie()                             //创建trie节点树
{
    Node *node=(Node*)malloc(sizeof(Node));
    memset(node,0,sizeof(Node));
    return node;
}

void insert_node(Trie_node root,char *str)      //trie树插入结点
{
    if(root ==NULL || *str=='\0')
        return;

    Node *t=root;
    while(*str!='\0')
    {
        if(t->child[*str-'a']==NULL)
        {
            Node *tmp=CreateTrie();
            t->child[*str-'a']=tmp;
        }
        t=t->child[*str-'a'];
        str++;
    }
    t->count++;
}


void search_str(Trie_node root,char *str)             //查找串是否在该trie树中
{
    if(NULL==root || *str=='\0')
    {
        printf("trie is empty or str is null\n");
        return;
    }

    Node *t=root;
    while(*str!='\0')
    {
        if(t->child[*str-'a']!=NULL)
        {
            t=t->child[*str-'a'];
            str++;
        }
        else
            break;
    }
    if(*str=='\0')
    {
        if(t->count==0)
            printf("该字符串不在trie树中,但该串是某个单词的前缀\n");
        else
            printf("该字符串在该trie树中\n");
    }
    else
        printf("该字符串不在trie树中\n");
}

void del(Trie_node root)      //释放整个字典树占的堆空间
{
    int i;
    for(i=0; i<MAX_CHILD; i++)
    {
        if(root->child[i]!=NULL)
            del(root->child[i]);
    }
    free(root);
}


int main()
{
    int i,n;
    char str[20];
    printf("请输入要创建的trie树的大小:");
    scanf("%d", &n);
    Trie_node root=NULL;
    root=CreateTrie();
    if(root==NULL)
        printf("创建trie树失败\n");
    for(i=0; i<n; i++)
    {
        scanf("%s",str);
        insert_node(root,str);
    }
    printf("trie树已建立完成\n");
    printf("请输入要查询的字符串:\n");
    while(scanf("%s",str)!=NULL)
    {
        search_str(root,str);
    }
    return 0;
 }


字典树的简单实现