静态字典树和动态字典树模板

以前做字典树一直用动态的字典树,每次开辟新空间,需要 new ,删除时delete, 这样动态,节省内存,却要每次开辟和释放空间,饿很难浪费时间,

静态字典树, 是事先开辟一块足够的空间,需要时区取,计较节省时间,有时候却浪费了不必要的内存,写静态字典树,可以开二维数组,也可以用结构体加上指针;

结构体 静态字典树模板

#define  MAX    26 //字符集大小

typedef struct TrieNode
{
    int nCount; //记录该字符出现次数
    struct TrieNode *next[MAX];
}TrieNode;

TrieNode Memory[1000000];
int allocp = 0;

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

/*创建新结点*/
TrieNode *CreateTrieNode()
{
    int i;
    TrieNode *p;

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

    return p;
}

/*插入*/
void InsertTrie(TrieNode **pRoot , char *s)
{
    int i , k;
    TrieNode *p;

    if(!(p = *pRoot))
    {
        p = *pRoot = CreateTrieNode();
    }
    i = 0;
    while(s[i])
    {
        k = s[i++] - 'a'; //确定branch
        if(p->next[k])
            p->next[k]->nCount++;
        else
            p->next[k] = CreateTrieNode();
        p = p->next[k];
    }
}

//查找
int SearchTrie(TrieNode **pRoot , char *s)
{
    TrieNode *p;
    int i , k;

    if(!(p = *pRoot))
    {
        return 0;
    }
    i = 0;
    while(s[i])
    {
        k = s[i++] - 'a'; 
        if(p->next[k] == NULL)    return 0;
        p = p->next[k];
    }
    return p->nCount;
}

 动态字典树模板

//专题地址http://vjudge.net/vjudge/contest/view.action?cid=51317#overview 此为动态字典树,静态字典树可自学。
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
typedef struct DT
{
    DT *chid[52];
    int end;
    DT()
    {
        end=0;
        memset(chid,0,sizeof(chid));
    }
}dt,*pdt;
pdt root;//定义根节点
int getnum(char s) //根据字符得到num
{
    if(s>='A'&&s<='Z')return s-'A';
    else return s-'a'+26;
}
void insert(char *s) //插入字符串到字典树
{
    pdt next=root;
    int num;
    for(int i=0;s[i];i++)
    {
        num=getnum(s[i]);
        if(next->chid[num]==NULL) //为空则申请内存
            next->chid[num]=new DT(); //开辟内存
        next=next->chid[num];
    }
    next->end=1; //字符串最末尾end赋值true
    return ;
}
int query(char *s) //查询字符串在字典树
{
    pdt next=root;
    int num;
    for(int i=0;s[i];i++)
    {
        num=getnum(s[i]);
        if(next->chid[num]==NULL) //没有此地址,返回未找到
            return 0;
        next=next->chid[num]; //继续查找
    }
    if(next->end) return 1; //找到返回true
    return 0;
}
void del(dt *rot) //递归删除字典树
{
    for(int i=0;i<52;i++)
        if(rot->chid[i]!=NULL)
            del(rot->chid[i]);
    delete rot;
}
char str[50002][50];
int main()
{
    root=new DT(); //根节点分配内存
    char a[]={"nihaoa"};
    insert(a);
    printf("%d %d
",query("nihaoa"),query("wobuhao")); //nihaoa存在 返回1 wobuhao不存在 返回0
    del(root); //删除字典树
    return 0;
}




www.cnblogs.com/tenlee
原文地址:https://www.cnblogs.com/tenlee/p/4420137.html