YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

字典树又称为前缀树,是一种用来统计字符串前缀数目的数据结构,字典树的实现相对于线段树等数据结构还是比较简单。

字典树的有3个核心函数,insert , search ,delete。

实现字典树常用的方式有俩种,一个是结构体+指针,还用一种是二维数组模拟,思想都是一样的。

1、首先定义字典树的节点:

class node{
public:
    int path;
    int end;
    node *mp[26];
    node (){
        path=end=0;
        for (int i=0;i<26;i++) 
            mp[i]=NULL;
    }
};

   节点中的path用来记录该节点被几个字符串用过。end用来记录以该节点结尾的字符串的个数。node *mp[26]是一个指针数组,我们可以用该数组记录该节点指向的下一个节点,数组大小为26指的是从a~z 26个英文字母,这个可以根据自己的寻求更改。比如说 x->mp[i]指的是节点x指向下一个值为i的节点。

2、节点的插入。

 

node *root = new node();
void insert(string s){
    node *now=root;
    int n=s.size();
    for(int i=0;i<n;i++){
        int id=s[i]-'a';
        if(root->mp[id]==NULL){
            root->mp[id]=new node();
        }
        root=root->mp[id];
        root->path++;
    }
    root->end++;
    root=now;
}

 

 

 

 

首先定义一个根节点指针。然后遍历字符串S的每一个字符,root->mp[id]!=NULL,说明遍历到目前为止,前缀字符串曾经出现过,即我们之前保存过的字符串和该字符串有共同的前缀。 如果root->mp[id]==NULL,说明该前缀第一次出现,要新申请一个节点用来保存当前字符,并作为上一个节点的儿子节点。root->path++; path记录的是该节点被几个字符串用过。没用一次+1就可以了。插入完之后 root->end++; 说明该节点为当前字符串的终止节点。

3、字符串的查找

int search(string s){
    node *now=root;
    int n=s.size();
    for(int i=0;i<n;i++){
        int id=s[i]-'a';
        if(now->mp[id]!=NULL){
            now=now->mp[id];
        }
        else return 0;//不存在. 
    }
    return now->path;
}

 

   查找保存过的字符串无非就是根据字符串s,从root出发能不能找到一条路径。如果找着找着没路了,即S没有遍历完遇到了NULL,那就没找到喽,否则返回path,意思的有树中哟普几个以该字符串为前缀的字符串。

4、字符串的删除

void de(string s){
    node *now=root;
    int n=s.size();
    for(int i=0;i<n;i++){
        int id=s[i]-'a'; 
        root->mp[id]->path--;
        if(root->mp[id]->path==0){
            root->mp[id]=NULL;
            return ;
        }
        root=root->mp[id];
    }
    root->end--;
    root=now;
}

 

   如果我们想要删除之前保存过的字符串,只需要修改每个节点的path,如果说该节点的path为0了,直接将指针指为空即可并退出,如果没有遇到path=0的情况,在最后节点的end--,说明以该节点为结尾的字符串减一。

 

 

 

class node{
public:
    int path;
    int end;
    node *mp[26];
    node (){
        path=end=0;
        for (int i=0;i<26;i++) 
            mp[i]=NULL;
    }
};
node *root = new node();
void insert(string s){
    node *now=root;
    if(root==NULL) return ;
    int n=s.size();
    for(int i=0;i<n;i++){
        int id=s[i]-'a';
        if(root->mp[id]==NULL){
            root->mp[id]=new node();
        }
        root=root->mp[id];
        root->path++;
    }
    root->end++;
    root=now;
}
int search(string s){
    node *now=root;
    int n=s.size();
    for(int i=0;i<n;i++){
        int id=s[i]-'a';
        if(now->mp[id]!=NULL){
            now=now->mp[id];
        }
        else return 0;//不存在. 
    }
    return now->path;
}
void de(string s){
    node *now=root;
    int n=s.size();
    for(int i=0;i<n;i++){
        int id=s[i]-'a'; 
        root->mp[id]->path--;
        if(root->mp[id]->path==0){
            root->mp[id]=NULL;
            return ;
        }
        root=root->mp[id];
    }
    root->end--;
    root=now;
}

 

 

 

 

 


        root->path++;
posted on 2020-12-02 12:49  Target--fly  阅读(236)  评论(0编辑  收藏  举报