日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

简单哈弗曼树(Java)

發(fā)布時(shí)間:2025/3/15 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单哈弗曼树(Java) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

哈夫曼樹的實(shí)現(xiàn)


?

  1.編碼思想

    哈夫曼編碼是一種變長(zhǎng)的編碼方案,字符的編碼根據(jù)使用頻率的的不同而長(zhǎng)短不一, 使用頻率高的字符其編碼較短,使用頻率低的字符編碼較長(zhǎng),從而使所有的編碼總長(zhǎng)度為最短.

  • 統(tǒng)計(jì)原始數(shù)據(jù)中個(gè)新號(hào)符號(hào)的頻率,安頻率高低的次序排列
  • 將兩個(gè)頻率最小的相加,作為原本兩個(gè)節(jié)點(diǎn)的父節(jié)點(diǎn),次父節(jié)點(diǎn)的頻率為子節(jié)點(diǎn)之和
  • 重復(fù)上述兩部,直到和為只剩下一個(gè)元素,那么這個(gè)元素就是根

  • ?

    ?????? 2.解碼思想

    ?????????? 利用Haffman樹進(jìn)行解碼,已知一個(gè)二進(jìn)制位串S,

       從串S的第一位出發(fā),逐位的去匹配二叉樹邊上標(biāo)記的0和1

       從haffman樹的根節(jié)點(diǎn)出發(fā),遇到0時(shí),向左,遇到1時(shí)向右,若干連續(xù)的0和1確定一條從根節(jié)點(diǎn)到某個(gè)葉子節(jié)點(diǎn)的路徑.一旦到達(dá)一個(gè)葉子節(jié)點(diǎn),便譯出一個(gè)字符,

       接著從S的下一個(gè)位開始繼續(xù)尋找,然后在重新將指針指向根.


    ?

    編碼和解碼操作

    主要有三部分

    1.對(duì)編碼進(jìn)行計(jì)數(shù),然后通過鍵值對(duì)構(gòu)造haffman樹,這里主要使用了優(yōu)先隊(duì)列,也就是最小堆,需要內(nèi)部節(jié)點(diǎn)類實(shí)現(xiàn)Comparable接口

    2.通過樹,返回葉節(jié)點(diǎn)的編碼,這里我利用Map<Character, String>這樣將字符和編碼綁定到了一起,方便后面操作

    3.根據(jù)輸入的字符串,遍歷,返回編碼后的字符串,如下:

    //toCode()返回一個(gè)Map鍵值對(duì)Map<Character, String> codes = haff.toCode() ;StringBuilder stringcode = new StringBuilder() ;//遍歷字符串,求其編碼for(char ch : text.toCharArray()) {stringcode.append(codes.get(ch)) ;}return stringcode.toString() ;

    下面是代碼演示:

    1 package com.jffx.util; 2 3 import java.util.*; 4 5 /* 6 本類負(fù)責(zé)邏輯處理, 7 負(fù)責(zé)串---->碼的編碼 8 嗎---->串的解碼 9 */ 10 public class HaffmanCode { 11 12 private Node root ; 13 14 15 //---------------------------------------- 下面是內(nèi)部節(jié)點(diǎn)類 16 static class Node implements Comparable<Node> { 17 Integer weight ; 18 String code = "" ; //取一個(gè)字符串域表示每個(gè)節(jié)點(diǎn)的編碼 19 Character data ; 20 21 Node parent ; 22 Node left ; 23 Node right ; 24 public Node(int w, Node left, Node right, Node parent) { 25 this.weight = w ; 26 this.left = left ; 27 this.parent = parent ; 28 this.right = right ; 29 } 30 31 @Override 32 public int compareTo(Node o) { 33 return this.weight - o.weight ; 34 } 35 36 @Override 37 public String toString() { 38 return "[" + this.data + ", " + this.weight + "]" ; 39 } 40 } 41 42 43 /** 44 * 構(gòu)造haffman樹 45 * 先將strs這樣的鍵值對(duì)轉(zhuǎn)化為節(jié)點(diǎn), 然后加入優(yōu)先隊(duì)列 46 * @param strs 字符--頻率這樣的鍵值對(duì) 47 */ 48 public HaffmanCode(Map<Character, Integer> strs) { 49 Queue<Node> queue = new PriorityQueue<>() ; 50 51 Set<Character> keys = strs.keySet() ; 52 for(Character key : keys) { 53 Node newNode = new Node(strs.get(key), null, null, null) ; 54 newNode.data = key ; 55 newNode.weight = strs.get(key) ; 56 57 //入堆 -- 覆寫CompareTo 58 queue.add(newNode) ; 59 } 60 61 while(queue.size() > 1) { 62 Node n1 = queue.poll() ; 63 Node n2 = queue.poll() ; 64 65 Node sumNode = new Node(n1.weight + n2.weight , n1, n2, null) ; 66 67 n1.parent = sumNode ; 68 n2.parent = sumNode ; 69 70 queue.add(sumNode) ; 71 } 72 73 this.root = queue.poll() ; 74 } 75 76 /** 77 * 將樹的葉節(jié)點(diǎn)的編碼返回, 返回的鍵值是 字符 -- 編碼 這樣的形式 78 * @return 79 */ 80 public Map<Character, String> toCode() { 81 Map<Character, String> map = new HashMap<>() ; 82 83 preTraverse() ; 84 85 //前序遍歷.將葉節(jié)點(diǎn)的屬性保存到map中 86 List<Node> stack = new LinkedList<>() ; 87 Node p = this.root ; 88 while(p != null || !stack.isEmpty()) { 89 while(p != null) { 90 stack.add(p) ; 91 p = p.left ; 92 } 93 //如果棧不空,去棧頂元素,然后向右 94 if(!stack.isEmpty()) { 95 p = ((LinkedList<Node>) stack).pop() ; 96 if(isLeafNode(p)) { 97 map.put(p.data, p.code) ; 98 } 99 p = p.right ; 100 } 101 } 102 return map ; 103 } 104 105 /** 106 * 輸入一串編碼,然后返回解碼后的字符串 107 * @return 108 */ 109 public String deCode(String codes) { 110 StringBuilder stringBuilder = new StringBuilder() ; 111 112 Node p = this.root ; //從根出發(fā) 113 for(int i = 0 ; i < codes.length() ; ++i) { 114 if(codes.charAt(i) == '0') { 115 p = p.left ; 116 } else { 117 p = p.right ; 118 } 119 if(isLeafNode(p)) { //如果是葉子 120 stringBuilder.append(p.data) ; 121 p = this.root ; 122 } 123 } 124 return stringBuilder.toString() ; 125 } 126 127 private void preTraverse() { 128 preTraverse(this.root) ; 129 } 130 private void preTraverse(Node root) { 131 if(root != null) { 132 if(root != this.root) { //如果不是根節(jié)點(diǎn) 133 if(root == root.parent.left) { //左孩子 134 root.code = root.parent.code + "0" ; 135 } else { 136 root.code = root.parent.code + "1" ; 137 } 138 } 139 //System.out.println(root) ; 140 preTraverse(root.left) ; 141 preTraverse(root.right) ; 142 } 143 } 144 145 public boolean isLeafNode(Node node) { 146 return node.left == null && node.right == null ; 147 } 148 149 150 151 152 153 154 155 156 157 /** 158 * 測(cè)試 159 * @param args 160 */ 161 public static void main(String[] args) { 162 String str = "today is Saturday." ; 163 164 char[] strCh = str.toCharArray() ; 165 Map<Character, Integer> map = new HashMap<>() ; 166 167 for(int i = 0 ; i < strCh.length ; ++i) { 168 if(map.containsKey(strCh[i])) { //如果存在鍵 169 map.put(strCh[i], map.get(strCh[i]) + 1) ; 170 } else { 171 map.put(strCh[i], 1) ; 172 } 173 } 174 175 HaffmanCode haff = new HaffmanCode(map) ; 176 177 String code = getTextCode(haff, str) ; 178 String decode = haff.deCode(code) ; 179 System.out.println(decode) ; 180 } 181 182 /** 183 * 獲取一個(gè)字符串的編碼 184 * @param text 需要壓縮的字符串 185 * @return 186 */ 187 public static String getTextCode(HaffmanCode haff, String text) { 188 189 Map<Character, String> codes = haff.toCode() ; 190 StringBuilder stringcode = new StringBuilder() ; 191 for(char ch : text.toCharArray()) { 192 stringcode.append(codes.get(ch)) ; 193 } 194 return stringcode.toString() ; 195 } 196 }

    ?


    這里你會(huì)發(fā)現(xiàn),你壓縮后的數(shù)據(jù)比你沒壓縮前還大,額--------


    學(xué)無止境

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/jffx/p/9997868.html

    總結(jié)

    以上是生活随笔為你收集整理的简单哈弗曼树(Java)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 黄色大片中文字幕 | 久草热播 | 久国久产久精永久网页 | 欧美性视频在线 | 99精品视频在线观看 | 日韩在线观看视频一区二区 | 精品久久久久久久免费人妻 | av在线麻豆| 亚洲精品在线免费播放 | 久久羞羞| 日韩视频在线一区 | 国产精品福利在线播放 | 国产日韩中文 | 亚洲经典自拍 | 黄色在线不卡 | 欧美青草视频 | 大咪咪dvd | 激情小视频 | 久久久久久久久久影院 | 91成人精品 | 免费在线观看的av | 欧美精品在线免费 | 日本黄区免费视频观看 | 日韩制服诱惑 | 在线v | av每日更新在线观看 | 黄色综合 | 少妇视频在线播放 | 欧美一区二区三区成人片在线 | 久久福利小视频 | 青草精品视频 | 成年人在线免费看 | 日本做爰全过程免费看 | 亚洲国产欧美视频 | 韩日视频在线观看 | 69视频在线观看 | 又大又粗欧美黑人aaaaa片 | 中文字幕乱视频 | 日韩视频中文字幕在线观看 | 成人69视频 | 欧美成人精品一区二区免费看片 | 91亚洲精品久久久久久久久久久久 | 国产区在线观看 | 亚洲三级免费观看 | 最近免费中文字幕大全免费版视频 | 色窝窝综合色窝窝久久 | 国产丝袜视频 | 在线观看国产区 | 成人黄网免费观看视频 | 成人欧美一区二区三区黑人 | 欧美精品久久久久久久自慰 | 蜜桃视频在线观看一区 | 狂躁美女大bbbbbb黑人 | 亚洲乱码国产乱码精品精软件 | 亚洲视频综合网 | 成人小视频在线免费观看 | xxxxx在线 | 国产精品高潮av | 狂躁美女大bbbbbb黑人 | 天海翼一区二区 | 性欧美视频在线观看 | 中文字幕久久精品 | 欧美色综合色 | 国产人成视频在线观看 | 日日操影院 | 天天搞夜夜 | 久色婷婷| 日韩精品一区二区av | 天堂av2019| 精品久久久一区二区 | 久久久精品福利 | 亚洲特级黄色片 | 蜜臀av性久久久久蜜臀aⅴ麻豆 | 最新黄色网址在线观看 | 欧美极品在线视频 | 国产美女一区二区三区 | 黄色免费网站在线 | 在线观看成人小视频 | 3o一40一50一6o女人毛片 | 日本欧美亚洲 | 一区黄色 | 99热一区二区 | 中国女人和老外的毛片 | 在线高清免费观看 | 性猛交xxxx乱大交孕妇印度 | 久久综合激情 | 亚洲国产欧美一区二区三区深喉 | 黄色免费网 | 成人精品三级 | 久久高清国产 | 欧洲激情网 | 高清一区二区三区四区 | 日本动漫艳母 | 国产毛片3 | 国产视频一区在线 | 91在线精品播放 | 成年人性生活视频 | 国产精品日日摸天天碰 | 晨勃顶到尿h1v1 |