日韩性视频-久久久蜜桃-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ò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 福利网址在线 | 污版视频在线观看 | 免费在线观看一区二区三区 | 成人午夜天 | 成人国产精品 | 国产成人亚洲综合 | 亚洲欧洲成人 | 男生插女生视频在线观看 | 丝袜熟女一区二区三区 | 福利在线播放 | 国产视频一区二区 | 娇喘顶撞深初h1v1 | 国产成人精品亚洲男人的天堂 | 一区二区三区小说 | 日本大尺度激情做爰hd | 欧美日韩国产区 | 一级片视频在线观看 | 插插久久| 99嫩草| 国产成人精品aa毛片 | 亚洲人视频 | 日韩高清不卡一区 | 免费看黄色漫画 | 亚洲高清网 | 亚洲欧美一区二区在线观看 | 一区二区三区www污污污网站 | 日本十八禁视频无遮挡 | 天堂av在线免费观看 | 色wwwwww| 欧美三级午夜理伦三级老人 | 国产精品另类 | 四虎成人影视 | 久久久综合网 | 大粗鳮巴久久久久久久久 | 天天爱夜夜操 | 九九热这里有精品视频 | 国产成人精品一区二区三区在线观看 | 国产a国产 | 国产尻逼视频 | 住在隔壁的她动漫免费观看全集下载 | 教练含着她的乳奶揉搓揉捏动态图 | 超碰伊人网 | 亚洲一区网站 | 国产黄色大全 | 欧美精品国产一区 | 精品三级在线 | 尤物影院在线观看 | 日韩激情欧美 | 韩国美女一区二区 | 成人午夜免费福利视频 | 亚洲第一男人天堂 | 黄色三级网站 | 97人妻精品视频一区 | 欧美暧暧视频 | av夜色| 我要操婊| 亚洲综合视频网 | 欧美一级色图 | 国产精品麻豆一区二区三区 | 国产精品区一区二区三 | 色综合久 | 奇米二区 | 欧美在线一区二区三区四区 | 国产精品午夜无码专区 | 五月的婷婷 | 影音先锋成人资源网 | 色老头一区二区三区在线观看 | 亚洲专区免费 | 日本泡妞视频 | 亚洲在线精品视频 | 向着小小的花蕾绽放 | 久久99精品久久只有精品 | 久久免费视频6 | 玩弄白嫩少妇xxxxx性 | 亚洲三级视频在线观看 | 乱老熟女一区二区三区 | 美国黄色一级视频 | 伦伦影院午夜理论片 | 一本一道久久综合狠狠老精东影业 | 老司机在线精品视频 | 精品久久久久久久久久久久久久 | 免费爱爱网址 | 亚洲精品乱码久久久久久黑人 | 天天做日日做 | 五月天在线播放 | avtt2015| 国产精品一区二区三区免费看 | 一级做a爰片久久毛片 | 成人免费xxxxx在线观看 | 日韩欧美高清一区 | 射网站 | 国产av一区二区三区最新精品 | 国产无套免费网站69 | 手机午夜视频 | 海角社区在线视频播放观看 | 国产三级国产精品 | 久久久久在线 | 狠狠久久综合 | 国产在线第二页 |