算法之字典树

概述

字典树以前缀存取数据,就像文件系统一样,从根出发,只要知道某段数据的前缀,就能找到相应的数据。
同时,当存入新数据时,需建立新节点,然后将新数据依次插入对应字段。
本例中字典树以英文小写字母的基础数据。

首先,将字符串分层:以一个字母对应一层,即一个字母占用一个节点。
从根节点出发,寻找下一个字母所在节点,若没有,则建立一个新节点,然后依次迭代。

伪代码

struct Node
    Node* child[26]
    bool flag;

INSERT( S, Trie )
    node = Trie.root
    for i=0 to S.size
        c = S[i] - 'a'
        if node.child[c] == NULL 
            node.child[c] = new Node
        node = node.child[c]
    node.flag = true

FIND( S, Trie )
    node = Trie.root
    for i=0 to S.size
        c = S[i] - 'a'
        if node.child[c] == NULL
            return false
        node = node.child[c]
    return node.flag

代码实现

const int SIZE = 26;

struct Node
{
    struct Node* child[SIZE];
    bool flag;
    Node( void )
    {
        memset( this, 0, sizeof(Node) );
    }
};

class Trie
{
public:
    Trie( void );
    ~Trie( void );
    void insert( const std::string str );
    bool find( const std::string str );
    void deleteTrie( Node* node );
private:
    Node* root;
};

Trie::Trie( void )
{
    root = new Node;
}

Trie::~Trie( void )
{
    deleteTrie(root);
}

void Trie::deleteTrie( Node* node )
{
    for( int i=0; i<SIZE; ++i ) {
        if( node->child[i] != NULL ) {
            deleteTrie( node->child[i] );
            node->child[i] = NULL;
        }
    }
    delete node;
    node = NULL;
}

void Trie::insert( const std::string str )
{
    int length = str.length();
    Node* node = root;
    for( int i=0; i<length; ++i ) {
        int c = str[i] - 'a';
        if( node->child[c] == NULL ) {
            node->child[c] = new Node;
        }
        node = node->child[c];
    }
    node->flag = true;
}

bool Trie::find( const std::string str )
{
    Node* node = root;
    int length = str.length();
    for( int i=0; i<length; ++i ) {
        int c = str[i] - 'a';
        if( node->child[c] == NULL ) {
            return false;
        }
        node = node->child[c];
    }
    return node->flag;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值