Trie树编程实现

Trie树

字典树,前缀树,单词查找树

应用:1)字符串检索 2)字符串最长公共前缀 3)英文单词的排序 4)作为其他数据结构和算法的辅助结构

结构图

    下面我们有and,as,at,cn,com这些关键词,那么如何构建trie树呢?下图是Trie的一种
trie_tree

节点存储内容:
  1. 只存是不是单词的标识,用于对已知字符串匹配
  2. 存储单个字母,用来查询或获取单词
特性
  1. 根节点不包含字符,除根节点外的每一个子节点都包含一个字符或者标识
  2. 从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串(针对于节点存储内容的第2种情况,其余情况不一定)
  3. 兄弟节点的前缀单词都相同
C++代码,节点只存储是否结束
#include <vector>
#include <string>

using namespace std;


class TrieNode {
public:
	TrieNode* next[26];
	bool isWord;
	// Initialize your data structure here.
	TrieNode() :isWord{false} {
		memset(next, 0, sizeof(next));
	};
};

class Trie {
public:
	Trie() {
		root = new TrieNode();
	}

	// Inserts a word into the trie.
	void insert(string word) {
		TrieNode* p = root;
		int len = word.length();
		for (int i = 0; i < len; i++){
			char c = word[i];
			int index = c - 'a';
			if(p->next[index]==NULL)  p->next[index] = new TrieNode();
			p = p->next[index];
		}
		p->isWord = true;
	}

	// Returns if the word is in the trie.
	bool search(string word) {
		TrieNode* p = root;
		int len = word.length();
		for (int i = 0; i < len&&p; i++){
			p = p->next[word[i]-'a'];
		}
		return p&&p->isWord;
	}

	// Returns if there is any word in the trie
	// that starts with the given prefix.
	bool startsWith(string prefix) {
		TrieNode* p = root;
		int len = prefix.length();
		for (int i = 0; i < len&&p; i++){
			p = p->next[prefix[i] - 'a'];
		}
		return p;
	}

private:
	TrieNode* root;
};

// Your Trie object will be instantiated and called as such:
// Trie trie;
// trie.insert("somestring");
// trie.search("key");
Java代码,节点存储字母
class TrieNode {
    // Initialize your data structure here.
    char val;
    boolean isEnd=false;
    TrieNode[] children=new TrieNode[26];
    public TrieNode() {}
    public TrieNode(char val) {
        this.val=val;
    }
}

public class Trie {
    private TrieNode root;

    public Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    public void insert(String word) {
        TrieNode index=root;
        char[] words=word.toCharArray();
        for(int i=0,len=words.length;i<len;++i){
            if(index.children[words[i]-'a']!=null){
                index=index.children[words[i]-'a'];
            }else{
                TrieNode node=new TrieNode(words[i]);
                index.children[words[i]-'a']=node;
                index=node;
            }
            
        }
        index.isEnd=true;
    }

    // Returns if the word is in the trie.
    public boolean search(String word) {
        TrieNode index=root;
        char[] words=word.toCharArray();
        for(int i=0,len=words.length;i<len;++i){
            if(index.children[words[i]-'a']!=null){
                index=index.children[words[i]-'a'];
            }else{
                return false;
            }
        }
        
        return index.isEnd?true:false;
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    public boolean startsWith(String prefix) {
        TrieNode index=root;
        char[] words=prefix.toCharArray();
        for(int i=0,len=words.length;i<len;++i){
            if(index.children[words[i]-'a']!=null){
                index=index.children[words[i]-'a'];
            }else{
                return false;
            }
        }
        

        return true;
    }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CuteXiaoKe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值