数据结构之Trie

云原生航海家
• 阅读 1571

Trie

什么是Trie

我们知道一个线性表的顺序查找的时间复杂度为O(n);二分搜索树的查找为O(log n),它们都和数据结构中的元素个数相关。关于线性表和二分搜索树的时间复杂度分析有需要的可以查看 Set集合和BinarySearchTree的时间复杂度分析

本文介绍的Trie字典树(主要用于存储字符串)查找速度主要和它的元素(字符串)的长度相关[O(w)]。

Trie字典树主要用于存储字符串,Trie 的每个 Node 保存一个字符。用链表来描述的话,就是一个字符串就是一个链表。每个Node都保存了它的所有子节点。

我们日常中使用的通讯录就是一个例子。

如果有N个条目,使用树结构查询的时间复杂度是O(logn)

而如果用Trie查询每个条目的时间复杂度与字段中一共有多少条目无关!时间复杂度为O(W)

W为查询单词的长度!

数据结构之Trie

每个节点有26个指向下个节点的指针

Class Node{
        char c;
        Node next[ 26];
}

在Trie中叶子节点并不一定是单词的结尾,像平底锅的英文是pan而熊猫是panda我们不能只根据叶子节点来区分单词的末尾,所以我们需要一个变量来存储当前节点是否是某个单词的结尾。

数据结构之Trie

class Node{
    boolean isWord;
    Map<char,Node> next;
}

特点

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

Trie字典树的新增

public class Trie {
        private class Node{
            public boolean isWord;
            public TreeMap<Character,Node> next;
            public Node() {
                this(false);
            }
            public Node(boolean isWord){
                this.isWord = isWord;
                next = new TreeMap<>();
            }
        }
        private Node root;
        private int size;
        public Trie(){
            root = new Node();
            size = 0;
        }
        //获得Trie中存储单词的数量
        public int getSize(){
            return size;
        }
        //向Trie中添加一个新的单词word
        public void add(String word){
            Node cur = root;
            for (int i = 0; i < word.length(); i++) {
                char c = word.charAt(i);
                if(cur.next.get(c) == null){
                    cur.next.put(c,new Node());
                }
                cur = cur.next.get(c);
            }
            if(!cur.isWord){
                cur.isWord = true;
                size ++;
            }
        }
}

Trie字典树的查询

    //查询单词word是否在Trie中
    public boolean contains(String word){
        Node cur = root;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);
            if (cur.next.get(c) == null){
                return false;
            }
            cur = cur.next.get(c);
        }
        return cur.isWord;
    }
    //查询是否在Trie中有单词以prefix为前缀
    public boolean isPrefix(String prefix){
        Node cur = root;
        for (int i = 0; i < prefix.length(); i++) {
            char c = prefix.charAt(i);
            if (cur.next.get(c) == null){
                return false;
            }
            cur = cur.next.get(c);
        }
        return true;
    }
点赞
收藏
评论区
推荐文章
林末 林末
5年前
折半查找-Python版(二分查找)
介绍二分查找也称折半查找(BinarySearch),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。前提必须待查找的序列有序时间复杂度O(log2n)原理1)确定该期间的中间位置K2)将查找的值t与arrayk比较,若相等,查找成功返回此位置;否则确定新的查找区域,继续二分
深入理解跳表及其在Redis中的应用
跳表可以达到和红黑树一样的时间复杂度O(logN),且实现简单,Redis中的有序集合对象的底层数据结构就使用了跳表。其作者威廉·普评价:跳跃链表是在很多应用中有可能替代平衡树的一种数据结构。本篇文章将对跳表的实现及在Redis中的应用进行学习。
Stella981 Stella981
4年前
DAT (Double Array Trie) 多模式匹配算法
一、简介:1.1、字典树trie:  字典树trie搜索关键码的时间和关键码自身及其长度有关,最快是0(1),,即在第一层即可判断是否搜索到,最坏的情况是0(n),n为Trie树的层数。由于很多时候Trie树的大多数结点分支很少,因此Trie树结构空间浪费比较多。  关键码检索策略可以根据关键码是否可以动态变化
Stella981 Stella981
4年前
Python数据结构与算法——散列(Hash)
!(https://oscimg.oschina.net/oscnet/19a7428dd9c64d149aa474d3aabe80ce.png)点击上方“蓝字”关注我们散列(Hash)对于一组数据项,顺序查找的时间复杂度是O(n),二分查找是O(logn),而对于散列的数据结构,
Wesley13 Wesley13
4年前
BFPRT线性查找算法
介绍:BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度。该算法的思想与快速排序思想相似,当然,为使得算法在最坏情况下,依然能达到o(n)的时间复杂度,五位算法作者做了精妙的处理。时间复杂度O(N)算法步骤
Wesley13 Wesley13
4年前
C++ 顺序表 代码实现
线性表存储在计算机中可以采用多种方式,以下是按照顺序存储方式实现:优点:查找很方便缺点:插入元素、删除元素比较麻烦,时间复杂度O(n)1ifndefSeqList_h2defineSeqList_h3include<iostream4usingnamespacestd;
贾蔷 贾蔷
8个月前
手把手教你实现哈希表:从代码到原理的新手友好指南
一、简介和应用哈希表(HashTable)是一种高效的数据结构,通过哈希函数将键(Key)映射到存储位置,实现O(1)时间复杂度的查找、插入和删除操作。它广泛应用于缓存系统、数据库索引、字典查询等场景。例如,在编程中需要快速根据用户ID查找信息时,哈希表能
Trie树简介及应用
Trie树在单词搜索、统计、排序等领域有大量的应用。文章从基础概念到具体的脏话过滤的应用、Redis的RAX和Linux内核的RadixTree对Trie树做了介绍。数据结构和算法是程序高性能的基础,本文抛砖引玉,希望大家对Trie树有所了解,并在未来开发过程实践和应用Trie树解决中类似情景的问题。
菜园前端 菜园前端
2年前
什么是时间复杂度?
原文链接:什么是时间复杂度?定性描述该算法的运行时间,一个函数、用大O表示,例如O(1)、O(n)、O(logN)...常见的时间复杂度量级常数阶O(1)对数阶O(logN)线性阶O(n)线性对数阶O(nlogN)平方阶O(n²)立方阶O(n)K次方阶O(
深入理解线段树 | 京东物流技术团队
线段树(SegmentTree)是常用的维护区间信息的数据结构,它可以在O(logn)的时间复杂度下实现单点修改、区间修改、区间查询(区间求和、区间最大值或区间最小值)等操作,常用来解决RMQ问题。RMQ(RangeMinimum/MaximumQuery
深入理解左倾红黑树 | 京东物流技术团队
平衡二叉搜索树平衡二叉搜索树(BalancedBinarySearchTree)的每个节点的左右子树高度差不超过1,它可以在O(logn)时间复杂度内完成插入、查找和删除操作,最早被提出的自平衡二叉搜索树是AVL树。AVL树在执行插入或删除操作后,会根据节
云原生航海家
云原生航海家
Lv1
为了赞美而去修行,有如被践踏的香花美草。
文章
4
粉丝
0
获赞
0