色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

數據結構字典樹的實現

算法與數據結構 ? 來源:bigsai ? 作者:bigsai ? 2021-09-07 15:03 ? 次閱讀

什么是字典樹字典樹,是一種空間換時間的數據結構,又稱Trie樹、前綴樹,是一種樹形結構(字典樹是一種數據結構),典型用于統計、排序、和保存大量字符串。所以經常被搜索引擎系統用于文本詞頻統計。它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。

可能大部分情況你很難直觀或者有接觸的體驗,可能對前綴這個玩意沒啥概念,可能做題遇到前綴問題也是暴力匹配蒙混過關,如果字符串比較少使用哈希表等結構可能也能蒙混過關,但如果字符串比較長、相同前綴較多那么使用字典樹可以大大減少內存的使用和效率。一個字典樹的應用場景:在搜索框輸入部分單詞下面會有一些神關聯的搜索內容,你有時候都很神奇是怎么做到的,這其實就是字典樹的一個思想。

對于字典樹,有三個重要性質:

1:根節點不包含字符,除了根節點每個節點都只包含一個字符。root節點不含字符這樣做的目的是為了能夠包括所有字符串。

2:從根節點到某一個節點,路過字符串起來就是該節點對應的字符串。

3:每個節點的子節點字符不同,也就是找到對應單詞、字符是唯一的。

一個字典樹

設計實現字典樹上面已經介紹了什么是字典樹,那么我們開始設計一個字典樹吧!

對于字典樹,可能不同的場景或者需求設計上有一些細致的區別,但整體來說一般的字典樹有插入、查詢(指定字符串)、查詢(前綴)。

我們首先來分析一下簡單情況吧,就是字符串中全部是26個小寫字母,剛好力扣208實現Trie樹可以作為一個實現的模板。

實現 Trie 類:

Trie() 初始化前綴樹對象。

void insert(String word) 向前綴樹中插入字符串 word 。

boolean search(String word) 如果字符串 word 在前綴樹中,返回 true(即,在檢索之前已經插入);否則,返回 false 。

boolean startsWith(String prefix) 如果之前已經插入的字符串 word 的前綴之一為 prefix ,返回 true ;否則,返回 false 。怎么設計這個字典樹呢?

對于一個字典樹Trie類,肯定是要有一個根節點root的,而這個節點類型TrieNode也有很多設計方式,在這里我們為了簡單放一個26個大小的TrieNode類型數組,分別對應‘a’-‘z’的字符,同時用一個boolean類型變量isEnd表示是否為字符串末尾結束(如果為true說明)。

class TrieNode {

TrieNode son[];

boolean isEnd;//結束標志

public TrieNode()//初始化

{

son=new TrieNode[26];

}

}

用數組的話如果字符比較多的話可能會消耗一些內存空間,但是這里26個連續字符還好的,如果向一個字典樹中添加big,bit,bz 那么它其實是這樣的:

那么再分析一下具體操作:

插入操作:遍歷字符串,同時從字典樹root節點開始遍歷,找到每個字符對應的位置首先判斷是否為空,如果為空需要創建一個新的Trie。比如插入big的枚舉第一個b時候創建TrieNode,后面也是同理。不過重要的是要在停止的那個TrieNode將isEnd設為true表明這個節點是構成字符串的末尾節點。

這部分對應的關鍵代碼為:

TrieNode root;

/** 初始化 */

public Trie() {

root=new TrieNode();

}

/** Inserts a word into the trie. */

public void insert(String word) {

TrieNode node=root;//臨時節點用來枚舉

for(int i=0;i《word.length();i++)//枚舉字符串

{

int index=word.charAt(i)-‘a’;//找到26個對應位置

if(node.son[index]==null)//如果為空需要創建

{

node.son[index]=new TrieNode();

}

node=node.son[index];

}

node.isEnd=true;//最后一個節點

}

查詢操作:查詢是建立在字典樹已經建好的情況下,這個過程和查詢有些類似但不需要創建TrieNode,如果枚舉的過程一旦發現該TrieNode未被初始化(即為空)則返回false,如果順利到最后看看該節點的isEnd是否為true(是否已插入已改字符結尾的字符串),如果為true則返回true。

這里用一個例子可能更好懂。插入big串,如果查找ba會因為第二次a對應TrieNode為null為為空。如果查找bi也會返回失敗,因為之前插入的big只在g字符對應TrieNode標識isEnd=true,但i字符下面的isEnd為false,即不存在bi字符串。

該部分對應的核心代碼為:

public boolean search(String word) {

TrieNode node=root;

for(int i=0;i《word.length();i++)

{

int index=word.charAt(i)-‘a’;

if(node.son[index]==null)//為null直接返回false

{

return false;

}

node=node.son[index];

}

return node.isEnd==true;

}

前綴查找:和查詢很相似但是有點區別,查找失敗的話返回false,但是如果能進行到最后一步那么返回true。上面例子插入big查找bi同樣返回true,因為存在以它為前綴的字符串。

該對應對應的核心代碼為:

public boolean startsWith(String prefix) {

TrieNode node=root;

for(int i=0;i《prefix.length();i++)

{

int index=prefix.charAt(i)-‘a’;

if(node.son[index]==null)

{

return false;

}

node=node.son[index];

}

//能執行到最后即返回true

return true;

}

上面代碼合在一起就是完整的字典樹了,最基礎的版本。完整版為:

22af1a8a-0f8c-11ec-8fb8-12bb97331649.png

代碼

字典樹小思考字典樹基礎班很容易,但很可能會出現一些延伸。

對于上面是26個字符的,我們很容易用ASCII找到對應索引,如果字符可能性比較多,用數組可能浪費的空間比較大,那我們也可以用HashMap或者List來存儲元素啊,用List的話就需要順序枚舉,用HashMap就可以直接查詢,這里就講解一個使用HashMap()實現的字典樹。

使用HashMap替代數組(不過使用哈希就不自帶排序功能了),其實邏輯是一樣的,只需要判斷時候用HashMap判斷是否存在對應的key即可,HashMap的類型為:

Map《Character,TrieNode》 sonMap;

使用HashMap實現的字典樹完整代碼為:

import java.util.HashMap;

import java.util.Map;

public class Trie{

class TrieNode{

Map《Character,TrieNode》 sonMap;

boolean idEnd;

public TrieNode()

{

sonMap=new HashMap《》();

}

}

TrieNode root;

public Trie()

{

root=new TrieNode();

}

public void insert(String word) {

TrieNode node=root;

for(int i=0;i《word.length();i++)

{

char ch=word.charAt(i);

if(!node.sonMap.containsKey(ch))//不存在插入

{

node.sonMap.put(ch,new TrieNode());

}

node=node.sonMap.get(ch);

}

node.idEnd=true;

}

public boolean search(String word) {

TrieNode node=root;

for(int i=0;i《word.length();i++)

{

char ch=word.charAt(i);

if(!node.sonMap.containsKey(ch))

{

return false;

}

node=node.sonMap.get(ch);

}

return node.idEnd==true;//必須標記為true證明有該字符串

}

public boolean startsWith(String prefix) {

TrieNode node=root;

for(int i=0;i《prefix.length();i++)

{

char ch=prefix.charAt(i);

if(!node.sonMap.containsKey(ch))

{

return false;

}

node=node.sonMap.get(ch);

}

return true;//執行到最后一步即可

}

}

前面講了,字典樹用于大量字符的統計、排序、儲存,其實排序就是和采用數組的方式可以進行排序,因為字符的ASCII有序,在讀取時候可以按照這個規則讀取,這個思想就和基數排序有點像了。

而統計的話可能會面臨數量上統計,可能是出現過次數或者前綴單詞數量統計,如果每次都枚舉可能有點浪費時間,但你可以TrieNode中添加一個變量,每次插入的時候可以統計次數。如果字符串有重復那可以直接添加,如果字符串要去重那可以確定插入成功再給路徑上前綴單詞總數分別自增。這個的話就要具體問題具體分析了。

此外,字典樹還有一個在ACM中用于解決求異或最值的問題,我們稱之為:01字典樹,大家感興趣也可以自行了解(后面可能會介紹)。

總結通過本文,想必你對字典樹有了一個較好的認識,本篇的話目的還是在于讓讀者能夠認識和學會基礎的字典樹,對其它變形優化能有個初步的認識。

字典樹可以最大限度地減少無謂的字符串比較,用于詞頻統計和大量字符串排序。自帶排序功能,使用中序遍歷序列即可得到排序序列。但是如果字符很多相同前綴很少的話那字典樹就沒啥效率優勢的(因為要一個一個訪問節點)。

字典樹的真實應用有很多,例如字符串檢索、文本預測、自動完成,see also,拼寫檢查、詞頻統計、排序、字符串最長公共前綴、字符串搜索的前綴匹配、作為其他數據結構和算法的輔助結構等等,這里就不再介紹啦。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7134

    瀏覽量

    89408
  • 內存
    +關注

    關注

    8

    文章

    3052

    瀏覽量

    74226
  • 字符串
    +關注

    關注

    1

    文章

    585

    瀏覽量

    20578

原文標題:字典樹,不就有點不一樣的一顆樹

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結構

    的一項技能。設備的起源設備(Device Tree)是一種描述硬件資源的數據結構,它由uboot傳遞給Linux內核,被內核解析,內核根據設備中的硬件描述信息加載利用相應驅動資源
    發表于 01-08 08:32

    飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結構

    的一項技能。設備的起源設備(Device Tree)是一種描述硬件資源的數據結構,它由uboot傳遞給Linux內核,被內核解析,內核根據設備中的硬件描述信息加載利用相應驅動資源
    發表于 01-07 09:16

    Python中dict支持多個key的方法

    ? 在Python中,字典(dict)是一種非常強大的數據結構,它允許我們通過鍵(key)來存儲和檢索值(value)。有時候,我們可能想要根據多個鍵來檢索或操作字典中的數據。雖然Py
    的頭像 發表于 11-29 15:59 ?204次閱讀

    DDC264配置寄存器數據寫入和320 DCLK時鐘脈沖后的回讀數據結構是什么?

    配置寄存器數據寫入和320 DCLK時鐘脈沖后的回讀數據結構是什么? 根據注和表9,16位配置寄存器數據,4位修訂ID, 300位校驗模式,怎么可能有1024 TOTAL READBACK BITS, format = 0
    發表于 11-19 07:58

    視覺軟件HALCON的數據結構

    在研究機器視覺算法之前,我們需要先了解機器視覺應用中涉及的基本數據結構。Halcon數據結構主要有圖像參數和控制參數兩類參數。圖像參數包括:image、region、XLD,控制參數包括:string、integer、real、handle、tuple數組等。
    的頭像 發表于 11-14 10:20 ?532次閱讀
    視覺軟件HALCON的<b class='flag-5'>數據結構</b>

    什么是默克爾(Merkle Tree)?如何計算默克爾根?

    01 默克爾的概念 默克爾(Merkle Tree)是一種特殊的二叉,它的每個節點都存儲了一個數據塊的哈希值。哈希值是一種可以將任意長度的數據
    的頭像 發表于 09-30 18:22 ?1079次閱讀
    什么是默克爾<b class='flag-5'>樹</b>(Merkle Tree)?如何計算默克爾根?

    架構師日記-從數據庫發展歷程到數據結構設計探析

    數據庫發展史 起初,數據的管理方式是文件系統,數據存儲在文件中,數據管理和維護都由程序員完成。后來發展出樹形結構和網狀
    的頭像 發表于 09-25 11:20 ?853次閱讀
    架構師日記-從<b class='flag-5'>數據</b>庫發展歷程到<b class='flag-5'>數據結構</b>設計探析

    嵌入式常用數據結構有哪些

    在嵌入式編程中,數據結構的選擇和使用對于程序的性能、內存管理以及開發效率都具有重要影響。嵌入式系統由于資源受限(如處理器速度、內存大小等),因此對數據結構的選擇和使用尤為關鍵。以下是嵌入式編程中常用的幾種數據結構,結合具體特點和
    的頭像 發表于 09-02 15:25 ?575次閱讀

    原理圖設計里兩顆重要的(國產EDA)

    原理圖里面兩顆重要的,那就是元件和網絡,作為EDA工具中的重要視圖和概念,雖然看似枯燥,但它們扮演著非常重要的角色,它們為電路圖的層次化結構提供了有力支撐。想象一個大型的電路設計
    的頭像 發表于 05-29 17:47 ?796次閱讀
    原理圖設計里兩顆重要的<b class='flag-5'>樹</b>(國產EDA)

    OpenHarmony語言基礎類庫【@ohos.util.Stack (線性容器Stack)】

    Stack基于數組的數據結構實現,特點是先進后出,只能在一端進行數據的插入和刪除。
    的頭像 發表于 05-10 15:54 ?521次閱讀
    OpenHarmony語言基礎類庫【@ohos.util.Stack (線性容器Stack)】

    揭秘編程核心:基本數據結構與算法思想詳解

    描述問題的數據除了各數據元素本身,還要考慮各元素的邏輯關系,主要是一對一的線性關系,一對多的型關系和多對多的圖形關系。
    的頭像 發表于 04-25 11:51 ?1139次閱讀
    揭秘編程核心:基本<b class='flag-5'>數據結構</b>與算法思想詳解

    探索編程世界的七大數據結構

    結構就像是一顆倒掛的小樹,有根、有枝、有葉。它是一種非線性的數據結構,以層級的方式存儲數據,頂部是根節點,底部是葉節點。
    的頭像 發表于 04-16 12:04 ?424次閱讀

    TASKING編譯器是否可以將數據結構設置為 \"打包\"?

    TASKING 編譯器是否可以將數據結構設置為 \"打包\"? GCC 很早以前就提供了這種可能性,可以將__attribute__((packed))與對齊指令結合使用。 對于
    發表于 03-05 06:00

    矢量與柵格數據結構各有什么特征

    矢量數據結構和柵格數據結構是地理信息系統(GIS)中最常用的兩種數據結構。它們在存儲和表示地理要素上有著不同的方法和特征。在接下來的文章中,我們將詳細介紹這兩種數據結構并比較它們的特點
    的頭像 發表于 02-25 15:06 ?2751次閱讀

    嵌入式軟件開發應該掌握哪些知識?

    掌握的知識 1.基礎知識 1.1 c/c++編程語言和數據結構 C/C++ 是嵌入式系統中常用的編程語言,因為它們提供了直接訪問硬件的能力。通過使用特定的編譯器和調用硬件相關的接口,可以實現對各種外設
    發表于 02-19 11:23
    主站蜘蛛池模板: 91精品免费久久久久久久久 | 欧美xxxxx18| 亚洲国产在线精品第二剧情不卡 | 果冻传媒在线观看视频 | caoporn 超碰免费视频 | 全彩黄漫火影忍者纲手无遮挡 | 亚洲国产精品线在线观看 | 欧美成人中文字幕在线视频 | 亚洲高清免费在线观看 | 亚洲午夜久久影院 | 强开乳罩摸双乳吃奶视频 | 冰山高冷受被c到哭np双性 | 午夜性爽视频男人的天堂在线 | 亚洲高清中文字幕免费 | 大睾丸内射老师 | 一区二区中文字幕在线观看 | 人妻天天爽夜夜爽三区麻豆A片 | 欧美伊人久久大香线蕉综合69 | 娇妻中日久久持久久 | 国语对白刺激真实精品 | 亚洲娇小性色xxxx | 亚洲乱妇88网 | 92国产精品午夜免费福利视频 | 97视频在线免费 | 日本xxxxxxxxx老师59 | 亚洲欧美日韩国产精品26u | 亚洲 欧美 综合 高清 在线 | 久久毛片免费看一区二区三区 | 全彩黄漫火影忍者纲手无遮挡 | 4480YY旧里番在线播放 | 处女座历史名人 | 中文中幕无码亚洲视频 | 免费人成视频19674不收费 | 欧美亚洲精品一区二三区8V | 久久免费看视频 | 国语自产一区第二页 | 出差无套内射小秘书 | 在线观看日本免费 | 久久综合一个色综合网 | 亚洲精品色婷婷在线蜜芽 | 窝窝影院午夜看片毛片 |