檔案壓縮總結(哈夫曼壓縮)
在學習哈弗曼壓縮之前,還是首先來了解什麼是哈夫曼樹,哈夫曼編碼。
1.哈夫曼樹是一種最優二叉樹,它的帶權路徑長度達到最小。樹的帶權路徑長度為所有葉子結點帶權路徑長度之和。
而結點的帶權路徑長度是結點的路徑長度乘以結點的權值。
2.哈夫曼編碼是依據字元出現概率來構造異字頭的平均長度最短的碼字。從哈弗曼樹的根結點開始,按照左子樹**為「0」,右子樹**為「1」的規則,直到樹的葉子結點,每個葉子結點的哈弗曼編碼就是從根結點開始,將途中經過的枝結點和葉子結點的**按順序串起來。
哈夫曼壓縮是位元組符號用乙個特定長度的01序列替代,在檔案中出現頻率高的符號,使用短的01序列,而出現頻率少的位元組符號,則用較長的01序列表示。
這裡的檔案壓縮,我還只能做簡單的 檔案a-->壓縮為檔案b--->解壓為檔案c,看檔案a和檔案c是不是相同。
那麼就要分兩個大步驟,小步驟:
不過,根據哈弗曼樹的特點,我們首先還是要定義結點型別
public class treenode然後分兩大步驟}
一. 首先壓縮檔案
1. 將原始檔a中資料按位元組讀取,然後用map統計每個位元組出現的次數(key--不同的位元組,value--次數)。
while (t != -1) else// 繼續讀取下乙個
t = bis.read();
}
2. 將map中的value值作為權值,建哈夫曼樹,並得到每個位元組的哈弗曼編碼。
/*** 建立哈樹
* @param nodequeue 已經得到的優先佇列
* @return 建立哈樹後,返回樹的根結點
*/public static treenode creattree(priorityqueuenodequeue)
nodequeue.add(root);
} return root;
}
/*** 得到哈樹 葉子結點的哈弗曼編碼
* @param node 哈樹的根結點
* @return 將葉子結點的 《位元組,編碼》存放入 map 中返回
*/public static hashmapgetcode(treenode node)
treenode left=node.left; // 獲得左孩子結點
if(left!=null)
treenode right=node.right; // 獲得右孩子結點
if(right!=null)
return codemap;
}
3. 壓縮關鍵(壓縮檔案的格式:碼表+檔案資訊)
再構造map(key--每個不同的位元組,value--哈弗曼編碼)。將檔案中的字串轉換成對應的哈弗曼編碼(即 0 1串)。將得到的0 1 串轉換成位元組(當最後不夠構成乙個位元組時,在後面新增0),並最後用乙個位元組記錄新增的0的個數。將整個map的資訊寫進檔案b,就是碼表。同時將得到的位元組寫進檔案b中。
length=writes.length(); //得到當前01串檔案的大小
if(length%8==0)
else
byte ws=new byte[length];
system.out.println("陣列的長度是:"+length);
while(writes.length()>0)else
讀取檔案中的位元組,並將其轉換成0 1串
int length=dis.readint();
system.out.println("-檔案的長度->"+length);
for(int j=0;j"+b);
string s=integer.tobinarystring(b);
system.out.println("-b的二進位制-->"+s+"--->"+s.length());
if(s.length()>8)else if(s.length()<8)
}m++;
}dos.close();
fos.close();
} catch (ioexception e)
}
這裡就基本上完成了檔案的壓縮和解壓了。
遇到的困難:
1. 之前建樹是個大問題,因為建哈弗曼樹涉及到了排序的問題,而每個結點又不是乙個簡單的資料型別,開始有嘗試過佇列和陣列來實現排序的問題,但在實現過程中,遇到很大困難,原因還是前面那個,結點的型別比較複雜,在樹形中當前結點交換位置影響到其孩子結點。開始還沒意識到這個大問題,總是不能把樹正確的搞出來,後來經龍哥指導才知道問題出在**。所有他建議使用優先佇列,這個好啊,太方便了。不過,說實在話,這個優先佇列在針對複雜的物件時,也還是要糾結一番啊,難懂。以後還要多多學習使用。
2. 開始對碼表的寫入也很是糾結,覺得這是個大問題,很複雜,不知道怎麼下手。後來經多次指點之前做過的畫圖板的儲存的檔案格式,類似完成碼表的寫入操作。
3. 還只是單檔案的壓縮和解壓,還不能實現大資料夾的壓縮
遇到的問題還是很多,感覺還是基礎太不紮實了,很多東西都不會用,而且總是不能有效利用前面學過的知識點,不能將所學系統聯絡起來。最要命的是特粗心,總是不注意細節,導致很多問題糾結很久,最後發現是出在小問題上。以後一定要特別注意這點。
哈夫曼壓縮
哈夫曼演算法 huffman 演算法是一種基於統計的壓縮方法。它的本質就是對文字檔案中的字元進行重新編碼,對於使用頻率越高的字元,其編碼也越短。但是任何2 個字元的編碼,是不能出現向前包含的。也就是說字元a 假設為00 的編碼的前段,不可能為字元b 則b的編碼不可能為001 因為這裡b 的編碼中包含...
哈夫曼壓縮
哈夫曼壓縮 哈夫曼壓縮是無失真壓縮的一種,一般用來壓縮文字和程式檔案。壓縮步驟 將要壓縮的檔案乙個乙個位元組地讀出來,統計每個位元組出現的次數 作為該葉子節點的權值 構建哈夫曼樹,採用優先佇列。遍歷哈夫曼樹,得到每乙個葉子節點的哈夫曼編碼。左0右1,得到的是01字串 將不足八位的01字串補0使其達到...
哈夫曼壓縮
size large 此文主要分析的是哈夫曼壓縮的重點包括統計字元頻率,建哈夫曼樹,生成碼表。哈夫曼壓縮是最常用的一種靜態無痕壓縮。以前也學習過哈夫曼的演算法結構,但是沒有自己去寫 實現,這次再學習了一遍,更加深刻理解哈夫曼壓縮的原理,如何真正實現檔案的壓縮節省記憶體資源。下面梳理下我的 和分析邏輯...