国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)】樹 - 前綴樹(Trie Tree)

這篇具有很好參考價值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)】樹 - 前綴樹(Trie Tree)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Trie,又稱字典樹、單詞查找樹或鍵樹,是一種樹形結(jié)構(gòu),是一種哈希樹的變種。典型應(yīng)用是用于統(tǒng)計,排序和保存大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計。它的優(yōu)點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。

什么是前綴樹

在計算機科學(xué)中,trie,又稱前綴樹或字典樹,是一種有序樹,用于保存關(guān)聯(lián)數(shù)組,其中的鍵通常是字符串。與二叉查找樹不同,鍵不是直接保存在節(jié)點中,而是由節(jié)點在樹中的位置決定。一個節(jié)點的所有子孫都有相同的前綴,也就是這個節(jié)點對應(yīng)的字符串,而根節(jié)點對應(yīng)空字符串。一般情況下,不是所有的節(jié)點都有對應(yīng)的值,只有葉子節(jié)點和部分內(nèi)部節(jié)點所對應(yīng)的鍵才有相關(guān)的值。

Trie 這個術(shù)語來自于 retrieval。根據(jù)詞源學(xué),trie 的發(fā)明者 Edward Fredkin 把它讀作/?tri?/ “tree”。但是,其他作者把它讀作/?tra?/ “try”。trie 中的鍵通常是字符串,但也可以是其它的結(jié)構(gòu)。trie 的算法可以很容易地修改為處理其它結(jié)構(gòu)的有序序列,比如一串?dāng)?shù)字或者形狀的排列。比如,bitwise trie 中的鍵是一串位元,可以用于表示整數(shù)或者內(nèi)存地址。trie 樹常用于搜索提示。如當(dāng)輸入一個網(wǎng)址,可以自動搜索出可能的選擇。當(dāng)沒有完全匹配的搜索結(jié)果,可以返回前綴最相似的可能。

前綴樹,數(shù)據(jù)結(jié)構(gòu)基礎(chǔ),數(shù)據(jù)結(jié)構(gòu),算法,java,面試,Powered by 金山文檔

上圖是一棵Trie樹,表示了關(guān)鍵字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。從上圖可以歸納出Trie樹的基本性質(zhì):

  • 根節(jié)點不包含字符,除根節(jié)點外的每一個子節(jié)點都包含一個字符。

  • 從根節(jié)點到某一個節(jié)點,路徑上經(jīng)過的字符連接起來,為該節(jié)點對應(yīng)的字符串。

  • 每個節(jié)點的所有子節(jié)點包含的字符互不相同。

  • 從第一字符開始有連續(xù)重復(fù)的字符只占用一個節(jié)點,比如上面的to,和ten,中重復(fù)的單詞t只占用了一個節(jié)點。

前綴樹的實現(xiàn)

重點在于節(jié)點數(shù)據(jù)結(jié)構(gòu),重要的插入和查找方法,以及遞歸和非遞歸兩種形式。

節(jié)點數(shù)據(jù)結(jié)構(gòu)定義

Node節(jié)點中使用map較為高效,用于映射到下一個節(jié)點:

public class Trie {
 
  private class Node{

      public boolean isWord; // 是否是某個單詞的結(jié)束
      
      public TreeMap<Character, Node> next; //到下一個節(jié)點的映射

      public Node(boolean isWord){
          this.isWord = isWord;
          //初始化字典樹
          next = new TreeMap<>();
      }

      public Node(){
          this(false);
      }
  }
  
  //根節(jié)點
  private Node root;
  //Trie單詞個數(shù)
  private int size;

  public Trie(){
      root = new Node();
      size = 0;
  }

  // 獲得Trie中存儲的單詞數(shù)量
  public int getSize(){
      return size;
  }

}

插入方法

  • 非遞歸方式

向Trie中添加一個新的單詞word: 將單詞拆分成一個個字符c,然后從根節(jié)點開始往下添加

public void add(String word){

    Node cur = root;
    //循環(huán)判斷新的cur節(jié)點是否包含下一個字符到下一個節(jié)點的映射
    for(int i = 0 ; i < word.length() ; i ++){
        //將c當(dāng)成一個節(jié)點插入Trie中
        char c = word.charAt(i);
        //判斷cur.next是不是已經(jīng)指向我們要找的c字符相應(yīng)的節(jié)點
        if(cur.next.get(c) == null){
            //新建節(jié)點
            cur.next.put(c, new Node());
        }
        //否則,就直接走到該節(jié)點位置即可
        cur = cur.next.get(c);
    }
    //判斷該單詞并不表示任何一個單詞的結(jié)尾
    if(!cur.isWord){
        //確定cur是新的單詞
        cur.isWord = true;
        size ++;
    }
}
  • 遞歸方式

/**
  * 向Trie中添加一個新的單詞word(遞歸寫法接口)
  *
  * @param word
  */
public void recursionAdd(String word) {
    Node cur = root;
    add(root, word, 0);
}

/**
  * 遞歸寫法調(diào)用方法實現(xiàn)遞歸添加
  *
  * @param node 傳入要進行添加的節(jié)點
  * @param word 傳入要進行添加的單詞
  */
public void add(Node node, String word, int index) {
    // 確定終止條件,這個終止條件在沒加index這個參數(shù)時,很難確定
    // 此時一個單詞已經(jīng)遍歷完成了,如果這個結(jié)束節(jié)點沒有標(biāo)記為單詞,就標(biāo)記為單詞
    if (!node.isWord && index == word.length()) {
        node.isWord = true;
        size++;
    }

    if (word.length() > index) {
        char addLetter = word.charAt(index);
        // 判斷trie的下個節(jié)點組中是否有查詢的字符,如果沒有,就添加
        if (node.next.get(addLetter) == null) {
            node.next.put(addLetter, new Node());
        }
        // 基于已經(jīng)存在的字符進行下個字符的遞歸查詢
        add(node.next.get(addLetter), word, index + 1);
    }
}

查詢單詞方法

  • 非遞歸方式

/**
  * 查詢單詞word是否在Trie中(非遞歸寫法)
  *
  * @param word
  * @return
  */
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;
        } else {
            cur = cur.next.get(c);
        }
    }
    return cur.isWord;
}
  • 遞歸方式

/**
  * 查詢單詞word中是否在Trie中接口(遞歸寫法)
  *
  * @param word
  * @return
  */
public boolean recursionContains(String word) {
    Node cur = root;
    return contains(root, word, 0);
}

/**
  * 查詢word中是否在Trie中遞歸寫法
  *
  * @param node
  * @param word
  * @param index
  * @return
  */
private boolean contains(Node node, String word, int index) {
    if (index == word.length()) {
        return node.isWord;
    }
    char c = word.charAt(index);
    if (node.next.get(c) == null) {
        return false;
    } else {
        return contains(node.next.get(c), word, index + 1);
    }
}

查詢前綴方法

  • 非遞歸方式

/**
  * 查詢是否在Trie中有單詞一prefix為前綴
  *
  * @param prefix
  * @return
  */
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;
}
  • 遞歸方式

/**
  * 查詢是否在Trie中有單詞一prefix為前綴(遞歸調(diào)用)
  *
  * @param prefix
  * @return
  */
public boolean recursionIsPrefix(String prefix) {
    Node node = root;
    return recursionIsPrefix(root, prefix, 0);
}

/**
  * 查詢是否在Trie中有單詞一prefix為前綴(遞歸實現(xiàn))
  *
  * @return
  */
public boolean recursionIsPrefix(Node root, String prefix, int index) {
    if (prefix.length() == index) {
        return true;
    }
    char c = prefix.charAt(index);
    if (root.next.get(c) == null) {
        return false;
    } else {
        return recursionIsPrefix(root.next.get(c), prefix, ++index);
    }
}

前綴樹的拓展

再深入理解下前綴樹。

前綴樹的復(fù)雜度

設(shè)平均查詢的query詞長n, 白名單m條記錄,平均長度k,

簡單單詞查詢:一個query,需要遍歷每一個白名單,調(diào)用query是否contains方法,contains方法遍歷前詞,找到頭元素一致,再遍歷判斷尾序列,contains的復(fù)雜度是O(n),整體復(fù)雜度是O(mn)

前綴樹查詢: 一個query,將這個query從頭到尾遍歷,每個元素在前綴樹中判斷,操作都是取下一個節(jié)點和判斷是否是end,時間復(fù)雜度是O(1),整體時間復(fù)雜度是O(n)

前綴樹有哪些應(yīng)用

這個比較簡單,就簡單列下:

  • 前綴匹配

  • 字符串檢索, 比如 敏感詞過濾,黑白名單等

  • 詞頻統(tǒng)計

  • 字符串排序

前綴樹的壓縮:基數(shù)樹

在計算機科學(xué)中,基數(shù)樹,或稱壓縮前綴樹,是一種更節(jié)省空間的 Trie(前綴樹)。對于基數(shù)樹的每個節(jié)點,如果該節(jié)點是確定的子樹的話,就和父節(jié)點合并?;鶖?shù)樹可用來構(gòu)建關(guān)聯(lián)數(shù)組。 用于 IP 路由。 信息檢索中用于文本文檔的倒排索引。

基數(shù)樹可看做是以二進制位串為關(guān)鍵字的 trie 樹,是一種多叉樹形結(jié)構(gòu),同時又類似多層索引表,每個中間節(jié)點包含指向多個子節(jié)點的指針數(shù)組,葉子節(jié)點包含指向?qū)嶋H的對象的指針(由于對象不具備樹節(jié)點結(jié)構(gòu),因此將其父節(jié)點看做葉節(jié)點)?;鶖?shù)樹也被設(shè)計成多道樹,以提高磁盤交互性能。同時,基數(shù)樹也是按照字典序來組織葉節(jié)點的,這種特點使之適合持久化改造,加上它的多道特點,靈活性較強,適合作為區(qū)塊鏈的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),構(gòu)建持久性區(qū)塊時較好地映射各類數(shù)據(jù)集合上?;鶖?shù)樹支持插入、刪除、查找操作。查找包括完全匹配、前綴匹配、前驅(qū)查找、后繼查找。所有這些操作都是 O(k)復(fù)雜度,其中 k 是所有字符串中最大的長度。

雙數(shù)組Trie樹(DoubleArrayTrie)

雙數(shù)組Trie樹(DoubleArrayTrie)是一種空間復(fù)雜度低的Trie樹,應(yīng)用于字符區(qū)間大的語言(如中文、日文等)分詞領(lǐng)域

雙數(shù)組Trie (Double-Array Trie)結(jié)構(gòu)由日本人JUN-ICHI AOE于1989年提出的,是Trie結(jié)構(gòu)的壓縮形式,僅用兩個線性數(shù)組來表示Trie樹,該結(jié)構(gòu)有效結(jié)合了數(shù)字搜索樹(Digital Search Tree)檢索時間高效的特點和鏈?zhǔn)奖硎镜腡rie空間結(jié)構(gòu)緊湊的特點。雙數(shù)組Trie的本質(zhì)是一個確定有限狀態(tài)自動機(DFA),每個節(jié)點代表自動機的一個狀態(tài),根據(jù)變量不同,進行狀態(tài)轉(zhuǎn)移,當(dāng)?shù)竭_結(jié)束狀態(tài)或無法轉(zhuǎn)移時,完成一次查詢操作。在雙數(shù)組所有鍵中包含的字符之間的聯(lián)系都是通過簡單的數(shù)學(xué)加法運算表示,不僅提高了檢索速度,而且省去了鏈?zhǔn)浇Y(jié)構(gòu)中使用的大量指針,節(jié)省了存儲空間。——《基于雙數(shù)組Trie樹算法的字典改進和實現(xiàn)》

具體可以看這篇文章

參考文章

  • https://blog.csdn.net/v_july_v/article/details/6897097

  • https://www.cnblogs.com/bonelee/p/8830825.html

  • https://blog.csdn.net/forever_dreams/article/details/81009580

  • https://www.jianshu.com/p/b9b8bf82fcd5

  • https://bestqiang.blog.csdn.net/article/details/89103524

  • https://java-sword.blog.csdn.net/article/details/89373156文章來源地址http://www.zghlxwxcb.cn/news/detail-732984.html

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)】樹 - 前綴樹(Trie Tree)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)與算法 | 二叉樹(Binary Tree)

    數(shù)據(jù)結(jié)構(gòu)與算法 | 二叉樹(Binary Tree)

    二叉樹(Binary Tree)是一種樹形數(shù)據(jù)結(jié)構(gòu),由節(jié)點構(gòu)成,每個節(jié)點最多有兩個子節(jié)點:一個左子節(jié)點和一個右子節(jié)點。 \\\"二叉樹\\\"(Binary Tree)這個名稱的由來是因為二叉樹的每個節(jié)點最多有兩個子節(jié)點,一個左子節(jié)點和一個右子節(jié)點。其中,“二叉”指的是兩個,因此“二叉樹

    2024年02月08日
    瀏覽(24)
  • 【算法基礎(chǔ)】java基礎(chǔ)——基本結(jié)構(gòu)、數(shù)據(jù)類型、表達式、語句

    Java程序的基本結(jié)構(gòu): ? ? ? ? 一段Java程序或者一個靜態(tài)庫,會用到下面7種語法 ? ? ? ? 1、原始數(shù)據(jù)類型:在計算機程序中精確到定義整數(shù)、浮點數(shù)、布爾值等 ? ? ? ? 2、語句:通過創(chuàng)建變量并對其賦值,它們能夠被組合為類似數(shù)學(xué)公式定義的表達式 ? ? ? ? 3、數(shù)組 ?

    2024年01月16日
    瀏覽(26)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】【12】前綴表達式、中綴表達式、后綴表達式

    【數(shù)據(jù)結(jié)構(gòu)與算法】【12】前綴表達式、中綴表達式、后綴表達式

    什么是前綴表達式、中綴表達式、后綴表達式 前綴表達式、中綴表達式、后綴表達式,是通過樹來存儲和計算表達式的三種不同方式 以如下公式為例 ( a + ( b ? c ) ) ? d ( a+(b-c) )*d ( a + ( b ? c ) ) ? d 通過樹來存儲該公式,可以表示為 那么問題就來了,樹只是一種抽象的數(shù)據(jù)

    2024年02月08日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)——前綴、中綴、后綴表達式實現(xiàn)和轉(zhuǎn)換(Java)

    數(shù)據(jù)結(jié)構(gòu)——前綴、中綴、后綴表達式實現(xiàn)和轉(zhuǎn)換(Java)

    1.7.1 概念 它們都是對表達式的記法,因此也被稱為前綴記法、中綴記法和后綴記法。它們之間的區(qū)別在于 運算符相對與操作數(shù)的位置 不同 前綴 表達式的運算符位于與其相關(guān)的 操作數(shù)之前 ;中綴和后綴同理。 平時我們 日常使用 并最為熟悉的就是中綴表達式。如: 1 + 2 *

    2024年02月05日
    瀏覽(28)
  • 初識Go語言25-數(shù)據(jù)結(jié)構(gòu)與算法【堆、Trie樹、用go中的list與map實現(xiàn)LRU算法、用go語言中的map和堆實現(xiàn)超時緩存】

    初識Go語言25-數(shù)據(jù)結(jié)構(gòu)與算法【堆、Trie樹、用go中的list與map實現(xiàn)LRU算法、用go語言中的map和堆實現(xiàn)超時緩存】

    ??堆是一棵二叉樹。大根堆即任意節(jié)點的值都大于等于其子節(jié)點。反之為小根堆。 ??用數(shù)組來表示堆,下標(biāo)為 i 的結(jié)點的父結(jié)點下標(biāo)為(i-1)/2,其左右子結(jié)點分別為 (2i + 1)、(2i + 2)。 構(gòu)建堆 ??每當(dāng)有元素調(diào)整下來時,要對以它為父節(jié)點的三角形區(qū)域進行調(diào)整。 插入元素

    2024年02月12日
    瀏覽(93)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】-哈夫曼樹(Huffman Tree)與哈夫曼編碼

    【數(shù)據(jù)結(jié)構(gòu)與算法】-哈夫曼樹(Huffman Tree)與哈夫曼編碼

    超詳細講解哈夫曼樹(Huffman Tree)以及哈夫曼編碼的構(gòu)造原理、方法,并用代碼實現(xiàn)。 路徑 :從樹中一個結(jié)點到另一個結(jié)點之間的 分支 構(gòu)成這兩個結(jié)點間的路徑。 結(jié)點的路徑長度 :兩結(jié)點間路徑上的 分支數(shù) 。 樹的路徑長度: 從樹根到每一個結(jié)點的路徑長度之和。記作: TL? 權(quán)

    2024年02月06日
    瀏覽(19)
  • 【高級數(shù)據(jù)結(jié)構(gòu)】Trie樹

    【高級數(shù)據(jù)結(jié)構(gòu)】Trie樹

    高效地存儲和查詢字符串的數(shù)據(jù)結(jié)構(gòu)。所以其重點在于:存儲、查詢兩個操作。 示例和圖片來自:https://blog.csdn.net/qq_42024195/article/details/88364485 假設(shè)有這么幾個字符串:b,abc,abd,bcd,abcd,efg,hii。最終存儲出來的Trie圖如下圖所示: 具體是怎么存的呢?對于每一個字符串,

    2024年03月10日
    瀏覽(22)
  • Java 【數(shù)據(jù)結(jié)構(gòu)】 二叉樹(Binary_Tree)【神裝】

    Java 【數(shù)據(jù)結(jié)構(gòu)】 二叉樹(Binary_Tree)【神裝】

    ? ? 登神長階 ?第五神裝 二叉樹 Binary-Tree 目錄 ???一.樹形結(jié)構(gòu) ??1.概念 ??2.具體應(yīng)用 ???二.二叉樹(Binary Tree) ??1.概念 ???2.表現(xiàn)形式 ??3.特殊類型 ??3.1完全二叉樹(Complete Binary Tree) ??3.2滿二叉樹(Full Binary Tree) ??4.性質(zhì)? ??5.二叉樹的遍歷 ??5.1前中后序遍歷

    2024年04月27日
    瀏覽(21)
  • 高級數(shù)據(jù)結(jié)構(gòu) Trie樹(字典樹)

    高級數(shù)據(jù)結(jié)構(gòu) Trie樹(字典樹)

    (Trie Tree)字典樹_Rkun18的博客-CSDN博客 構(gòu)造字典樹 這里使用維基百科里的一幅圖舉例,由于只是舉例,使用較小的26個字母,把大小寫統(tǒng)一規(guī)定成小寫,圖里’A’變成’a’,方便構(gòu)造樹 先序遍歷 main方法運行: Trie獲取所有單詞 深度搜索trie樹,對于正在搜索的節(jié)點node 遍歷

    2024年02月02日
    瀏覽(23)
  • 【數(shù)據(jù)結(jié)構(gòu)】深刨Trie樹(字典樹)

    【數(shù)據(jù)結(jié)構(gòu)】深刨Trie樹(字典樹)

    Trie 樹,也叫“字典樹”。顧名思義,它是一個樹形結(jié)構(gòu)。它是一種專門處理字符串匹配的數(shù)據(jù)結(jié)構(gòu),用來解決在一組字符串集合中快速查找某個字符串的問題。 Trie 樹的本質(zhì),就是利 用字符串之間的公共前綴,將重復(fù)的前綴合并在一起 。 舉個例子,現(xiàn)在我們要存儲一些字

    2023年04月13日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包