本文主要介javascript trie單字查找樹的範例,詳細的介紹了trie的概念和實現,具有一定的參考價值,有興趣的小夥伴們可以參考一下,希望能幫助到大家。
引子
Trie樹(來自單字retrieval),又稱前綴字,單字找出樹,字典樹,是一種樹狀結構,是一種哈希樹的變種,是一種用於快速檢索的多叉樹結構。
它的優點是:最大限度地減少無謂的字串比較,查詢效率比雜湊表高。
Trie的核心思想是空間換時間。利用字串的公共前綴來降低查詢時間的開銷以達到提高效率的目的。
Trie樹也有它的缺點, 假定我們只對字母與數字進行處理,那麼每個節點至少有52+10個子節點。為了節省內存,我們可以用鍊錶或數組。在JS中我們直接用數組,因為JS的數組是動態的,自帶優化。
基本性質
-
根節點不包含字符,除根節點外的每個子節點都包含一個字元
從根節點到某一節點。路徑上經過的字元連接起來,就是該節點對應的字串
每個節點的所有子節點所包含的字元都不相同
程式實作
// by 司徒正美 class Trie { constructor() { this.root = new TrieNode(); } isValid(str) { return /^[a-z1-9]+$/i.test(str); } insert(word) { // addWord if (this.isValid(word)) { var cur = this.root; for (var i = 0; i <p></p><p>我們將重點來看TrieNode與Trie的insert方法。 由於字典樹是主要用在詞頻統計,因此它的節點屬性比較多, 包含了numPass, numEnd但非常重要的屬性。 </p><p>insert方法是用於插入重詞,在開始之前,我們必須判定單字是否合法,不能出現 特殊字元與空白。插入時是打散了一個個字元放入每個節點。每經過一個節點都要修改numPass。 </p><p>優化<br></p><p>現在我們每個方法中,都有一個c=-48的操作,其實數字與大寫字母與小寫字母間其實還有其他字元的,這樣會造成無謂的空間的浪費</p><p></p><pre class="brush:php;toolbar:false">// by 司徒正美 getIndex(c){ if(c 97 return c - 97 + 26+ 11 } }
然後相關方法將c-= 48改成c = this.getIndex(c)即可
測試
var trie = new Trie(); trie.insert("I"); trie.insert("Love"); trie.insert("China"); trie.insert("China"); trie.insert("China"); trie.insert("China"); trie.insert("China"); trie.insert("xiaoliang"); trie.insert("xiaoliang"); trie.insert("man"); trie.insert("handsome"); trie.insert("love"); trie.insert("Chinaha"); trie.insert("her"); trie.insert("know"); var map = {} trie.preTraversal(function(node, str){ if(node.isEnd){ map[str] = node.numEnd } }) for(var i in map){ console.log(i+" 出现了"+ map[i]+" 次") } console.log("包含Chin(包括本身)前缀的单词及出现次数:"); //console.log("China") var map = {} trie.preTraversal(function(node, str){ if(str.indexOf("Chin") === 0 && node.isEnd){ map[str] = node.numEnd } }) for(var i in map){ console.log(i+" 出现了"+ map[i]+" 次") }
#Trie樹和其它資料結構的比較
Trie樹與二元搜尋樹
二元搜尋樹應該是我們最早接觸的樹結構了,我們知道,當資料規模為n時,二元搜尋樹插入、尋找、刪除操作的時間複雜度通常只有O(log n),最壞情況下整棵樹所有的節點都只有一個子節點,退變成一個線性表,此時插入、查找、刪除操作的時間複雜度是O( n)。
通常情況下,Trie樹的高度n要遠大於搜尋字串的長度m,故查找操作的時間複雜度通常為O(m),最壞情況下的時間複雜度才為O (n)。很容易看出,Trie樹最壞情況下的查找也快過二元搜尋樹。
文中Trie樹都是拿字符串舉例的,其實它本身對key的適宜性是有嚴格要求的,如果key是浮點數的話,就可能導致整個Trie樹巨長無比,節點可讀性也非常差,這種情況下是不適宜用Trie樹來保存資料的;而二元搜尋樹就不存在這個問題。
Trie樹與Hash表
考慮Hash衝突的問題。 Hash表通常我們說它的複雜度是O(1),其實嚴格說起來這是接近完美的Hash表的複雜度,另外還需要考慮到hash函數本身需要遍歷搜尋字串,複雜度是O(m )。在不同鍵被映射到「同一個位置」(考慮closed hashing,這「同一個位置」可以由一個普通鍊錶來取代)的時候,需要進行查找的複雜度取決於這「同一個位置」下節點的數目,因此,在最壞情況下,Hash表也是可以成為一張單向鍊錶的。
Trie樹可以比較方便地按照key的字母序來排序(整棵樹先序遍歷一次就好了),這跟絕大多數Hash表是不同的(Hash表一般對於不同的key來說是無序的)。
在較理想的情況下,Hash表可以以O(1)的速度迅速命中目標,如果這張表非常大,需要放到磁碟上的話,Hash表的查找訪問在理想情況下只需要一次即可;但是Trie樹存取磁碟的數目需要等於節點深度。
很多時候Trie樹比Hash表需要更多的空間,我們考慮這種一個節點存放一個字元的情況的話,在保存一個字串的時候,沒有辦法把它保存成一個單獨的區塊。 Trie樹的節點壓縮可以明顯緩解這個問題,後面會講到。
Trie樹的改進
按位Trie樹(Bitwise Trie)
原理上和普通Trie樹差不多,只不過普通Trie樹存儲的最小單位是字符,但是Bitwise Trie存放的是位而已。位元資料的存取由CPU指令一次直接實現,對於二進位數據,它理論上要比普通Trie樹快。
節點壓縮。
分支壓縮:對於穩定的Trie樹,基本上都是尋找和讀取操作,完全可以把一些分支進行壓縮。例如,前圖中最右側分支的inn可以直接壓縮成一個節點“inn”,而不需要作為一棵常規的子樹存在。 Radix樹就是根據這個原理來解決Trie樹過深的問題。
節點映射表:這種方式也是在Trie樹的節點可能已經幾乎完全確定的情況下採用的,針對Trie樹中節點的每一個狀態,如果狀態總數重複很多的話,透過一個元素為數字的多維數組(例如Triple Array Trie)來表示,這樣儲存Trie樹本身的空間開銷會小一些,雖說引入了一張額外的映射表。
前綴樹的應用
前綴樹還是很好理解,它的應用也是非常廣的。
(1)字串的快速檢索
字典樹的查詢時間複雜度是O(logL),L是字串的長度。所以效率還是比較高的。字典樹的效率比hash表高。
(2)字串排序
從上圖我們很容易看出單字是排序的,先遍歷字母序在前面。減少了沒必要的公共子字串。
(3)最長公共前綴
inn和int的最長公共前綴是in,遍歷字典樹到字母n時,此時這些單字的公共前綴是in。
(4)自動比對前綴顯示字尾
我們使用字典或是搜尋引擎的時候,輸入appl,後面會自動顯示一堆前綴是appl的東東吧。那麼有可能是透過字典樹實現的,前面也說了字典樹可以找到公共前綴,我們只需要把剩餘的後綴遍歷顯示出來即可。
相關推薦:
關於uery EasyUI 結合ztrIee的後台頁面開發教學
以上是javascript trie前綴樹程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3漢化版
中文版,非常好用

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能