day13優先級隊列&哈夫曼樹&Trie

優先級隊列(Priority Queue)

優先級隊列也是個隊列,因此也是有這和隊列差不多的設計方法,唯一不同的就是多了一個優先級,普通的隊列是遵循FIFO原則,也就是先進先出,優先級隊列則是按照優先級高低進行出隊,比如將優先級最高的元素作為隊頭優先出列

優先級隊列的應用場景舉例

醫院的夜間門診

隊列元素是病人

優先級是病情的嚴重情況,掛號時間

操作系統的多任務調度

隊列元素是任務

優先級是任務類型

接口設計

int size();//元素的數量

boolean isEmpty();//是否為空

void enQueue(E element);//入隊

E deQueue();//出隊

E front;//獲取隊列的頭元素

void clear();//清空

優先隊列的底層實現

PriorityQueue


測試圖

底層是直接利用二叉堆左右優先隊列實現的,通過Person自定義CompareTo方法,比較數字大小,從而定義優先級高低


哈夫曼編碼(Huffman Coding)

哈夫曼編碼,又稱為霍夫曼編碼,它是現代壓縮算法的基礎;

假設現在要把字符串[ABBBCCCCCCCCDDDDDDEE]轉成二進制編碼進行傳輸,可以轉成ASCII編碼(65~69,1000001~1000101),但是會發現結果有點冗長,于是我們可能想到用更短的約定的編碼格式來定義,例如:

A:000;B:001;C:010;D:011;E:100,這樣我們就可以簡單方面的將上面的字符串轉換成:

000 001001001 010010010010010010010010010 011011011011011011 100 一共20個字母,轉成了60個二進制位,使用哈夫曼編碼,可以壓縮成更少的二進制位;

哈法曼樹

先計算出每個字母出現的頻率(權值,這里直接用出現的次數)

權值

利用這些權值,構建一棵哈弗曼樹(又稱為霍夫曼樹,最優二叉樹)

1.以權值作為根節點構建n棵二叉樹,組成森林

2.在森林中選出2個根節點最小的樹合并,并作為一棵新樹的左右子樹,且新樹的根節點為其左右子樹根節點之和

3.從森林中刪除剛才選取的2棵樹,并將新樹加入森林

4.重復2,3步驟,知道森林只剩一棵樹為止,該樹即為哈弗曼樹

上面的步驟轉化為如下圖所示:

構建哈弗曼樹

構建哈夫曼編碼

哈夫曼樹

left為0,right為1,可以得出A,B,C,D,E5個字母對應的哈弗曼編碼

構建哈夫曼編碼

[ABBBCCCCCCCCDDDDDDEE]的哈夫曼編碼是:1110110110110000000001010101010101111

哈夫曼編碼總結

n個權值構建出來的哈夫曼樹擁有n個葉子節點,每個哈夫曼編碼都不是另一個哈夫曼編碼的前綴,哈夫曼樹是帶權路徑長度最短的樹,權值較大的節點離根節點較近;(帶權路徑長度:樹中所有的子節點的權值乘上其到根節點的路徑長度,與最終的哈夫曼編碼總長度成正比關系)


Trie

Trie 也叫做字典樹,前綴樹(Prefix Tree),單詞查找樹;Trie搜索字符串的效率主要跟字符串的長度有關


Trie 接口設計

Trie接口設計

Trie 展示圖

Trie 存放圖

上面的展示Trie村粗cat,dog,doggy,does,cast,add6個單詞

紅色代表單詞結束。

Trie實現代碼圖

構建節點代碼

節點構造

parent:刪除時候由后往前刪除需要用到

HashMap<Character,Node<V>> children;存儲對象,Character代表字母作為key,也就是d o g,Node<V>作為value,存儲相關子節點數據

Character character:存儲的key,刪除時候使用

V value:紅色節點存儲的值,紅色節點也代表一個單詞介紹

boolean word;是否為單詞的結尾,代表單詞是否結束


獲取node代碼

node

會發現之后很多方法都會用到這個node方法,所以這里就不進一步作單詞的判斷,直接返回node節點按照外面的邏輯進行處理

獲取節點方法get和包含方法判斷

get&contains

通過word是否為true來判斷要尋找的單詞是否存在

前綴方法

startsWith

添加方法

add

添加單詞方法重點就是如果沒有子節點就創建子節點,如果有子節點的話,就判斷單詞是否存在,存在就替換,不存在就新增

刪除方法

remove

刪除方法相對于增加方法來說,會稍微麻煩一點,需要判斷是否還有子節點,針對子節點是否存在的情況進行相關處理

Trie總結

Trie的優點:搜索前綴的效率主要跟前綴的長度有關

Trie的缺點:需要消耗大量的內存,因此還有待改進(一個字符對應一個節點,二叉樹一個單詞對應一個節點,所以相對來說內存消耗大)

demo相關地址

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 2019.5.25 周六 天氣晴 堅持分享第78天 525我??我,還能記得大學心協搞得一些活動。愛自己,才能愛家...
    嵐清H閱讀 258評論 0 0
  • 【同讀一本書】 2016-03-09-036 《影響力》 【原文】: 隱藏在這一技巧背后的理論是:那些剛剛表明了自...
    楊平的閱讀 408評論 0 0
  • 相信堅持總有進步吧
    佳木不朽閱讀 395評論 2 2
  • 棉花糖似的云朵, 聚散 飄逸。 天空里, 你用一片純潔, 靜靜地襯托著那份藍。 清風吹來, 你把天空當作舞臺, 拂...
    另類_074d閱讀 363評論 4 2