Trie,又称字典树、单词查找树,是一种树形结构

原贴:http://blog.csdn.net/Terro/archive/2007/08/15/1745699.aspx

Trie,又称字典树、单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。

它有3个基本性质:

1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3. 每个节点的所有子节点包含的字符都不相同。

Trie的实现见下面的代码,具体操作见注释。这个写的有些垃圾,期待改进。

 

//结点类型
typedef struct node
{
    
bool isStr;    //记录此处是否有串,目的是:如果插入"abc",那么"ab"如果不作标记的话,也是存在的
    int count;    //记录子结点的个数
    node* next[26];    //孩子的指针
    node()
        : count(
0), isStr(false)
    
{
        memset(next, NULL, 
sizeof(next));    //初始化为空
    }

}
 *nodeptr;
//Trie类
//insert:插入一个字符串,重复插入无效
//remove:删除指定的字符串,如果不存在,则不进行操作
//find:判断是否有指定的字符串
class Trie
{
private:
    nodeptr root;
    
//删除t的孩子的孩子
    
//这样做的原因是
    
//delete一个指针,这个指针就不确定了,不能继续向上操作
    
//所以只能删除t的孩子的孩子
    
//有待改进
    void remove(nodeptr t, const char* key, int i)
    
{
        
//孩子的指针,key[i]为孩子
        nodeptr pnext = t -> next[key[i] - 'a'];
        
if (key[i+1&& pnext)    //不是最后一个结点
        {
            pnext 
-> count--;
            remove(pnext, key, i
+1);    //递归删除
        }

        
if (!pnext -> count)    //子结点是空的,直接删除
            delete pnext;
        
else    //否则删除子结点的孩子的指针
            pnext -> next[key[i+1- 'a'= NULL;
    }

public:
    Trie()
    
{
        root 
= new node;
    }

    
//插入操作
    void insert(const char* key)
    
{
        nodeptr location 
= root;
        
do
        
{
            
if (location -> next[*key - 'a'== NULL)    //不存在则新建
            {
                nodeptr tmp 
= new node;
                location 
-> next[*key - 'a'= tmp;
            }

            
if (*key)    //不是0
            {
                location 
-> count++;
                location 
= location -> next[*key - 'a'];
            }

        }
 while (*key++);
        location 
-> isStr = true;    //到达尾部
    }

    
//删除操作
    void remove(const char* key)
    
{
        
if (!find(key))    //找不到则不操作
            return;
        
//预处理根
        root -> count--;
        
//删除根的子结点
        remove(root, key, 0);
        
//尾处理
        if (!root -> next[*key - 'a'-> count)
            delete root 
-> next[*key - 'a'];
        
else
            root 
-> next[*key - 'a'= NULL;
    }

    
//查找
    bool find(const char* key)
    
{
        nodeptr location 
= root;
        
while (*key && location)
            location 
= location -> next[*key++ - 'a'];
        
return (location != NULL && location -> isStr);
    }

}
;


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1745699

 
阅读更多
个人分类: 算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭