C 霍夫曼二叉樹壓縮演算法實現

2022-08-26 09:15:12 字數 4064 閱讀 7337

知道有的人比較懶,直接貼全部**.

一開始一次性code完了壓縮部分**.只除錯了2,3次就成功了.

一次性寫150行**,沒遇到什麼bug的感覺還是蠻爽的.

寫解壓**,才發現壓縮**有些細節問題.

對最後乙個字元處理問題.

遇到比較折騰點:構建二叉樹時,把原本應該是(葉結點的有值的)節點放在了左節點,正確應該放在右節點,導致生成的編碼序列不滿足(任意編碼不是其他編碼的字首).導致解碼失敗.

使用方法:

var srcdata = encoding.utf8.getbytes(textbox1.text);

var cpsdata = compress(srcdata);

treeview1.expandall();

var depdata = decompress(cpsdata);

var depstr = encoding.utf8.getstring(depdata );

這個treeview就是顯示二叉樹的,要新增控制項,或者刪除**.

快速理解:

1.此壓縮直接對位元組流進行壓縮.

2.壓縮原理:位元組流對每個直接使用率不平均,所以用變長的編碼對256個位元組重新編碼,以較短的編碼表示使用率高的位元組,較長編碼表示使用率低的位元組.

所以總體來看,用新的編碼表示的位元組流要比原來的短.(除非位元組流特別小,壓縮效果就不好)

3.由於二叉樹的性質,將使用率低的先加入樹,使用率高的後加入作為使用率低的節點的父節點的兄弟節點(因為有值的節點必須是葉結點).從最底下向上構建

二叉樹.

1

using

system;

2using

system.collections.generic;

3using

system.componentmodel;

4using

system.data;

5using

system.drawing;

6using

system.linq;

7using

system.text;

8using

system.windows.forms;

9using

system.io;

1011

namespace

霍夫曼二叉樹壓縮

1221

22private

void button1_click(object

sender, eventargs e)

2330

31 dictionary diccode = new dictionary();

32byte compress(byte

data)

3341

var orderasccounts = everycount.orderby(a=>a.value);

42 queuequecouts = new queue();

43 orderasccounts.tolist().foreach(d =>);

45});

46 buildtree(ref

quecouts);

47foreach (var a in

bnode.nodes)

4852 bnode root = bnode.nodes[0

];53

while(root.parent!=null)56

createtreeview(root,treeview1.nodes);

57string curcode = ""

;58 list outdata = new list();

59foreach (var d in

data)

6068}69

if (curcode != "")70

7576

return

outdata.toarray();77}

7879

byte decompress(byte

data)

8086 codes += getcode(data[data.length-1]).trimend('0'

);87

var bdata =getcode(codes);

8889

return

bdata;90}

9192

byte getbytebycode(string

curcode)

9396

byte getcode(string

code)

97112

}113

if (p == -1

)114

117 }while(code.length>0

);118

119/*

for (int i = 1; pos + i < code.length ; i++)

120131

132else if (pos + i == code.length - 1 && second.count() > 0)

133datas.add( (byte)second.first().key );

134}

*/135

return

datas.toarray();

136}

137string getcode(byte

b )138

141string

getcode(bnode a)

142147

148 bnode buildtree(ref queuequecouts )

149 : first.node;

154155

var rgt = second.node == null ? new bnode : second.node;

156157

if (rgt.key == -1

)158

164165

var pnode = new

bnode

166;

169 lft.isleft = true

;170 rgt.isleft = false

;171 pnode.left =lft;

172 pnode.right =rgt;

173 lft.parent =pnode;

174175 rgt.parent =pnode;

176if (lft.key != -1

)177

bnode.nodes.add(lft);

178if (rgt.key != -1

)179

bnode.nodes.add(rgt);

180if (quecouts.count > 0

));182

var orderque = quecouts.orderby(q =>q.count).tolist();

183quecouts.clear();

184foreach (var a in

orderque)

185quecouts.enqueue(a);

186return buildtree(ref

quecouts);

187}

188else

189return

pnode;

190}

191192

void

createtreeview(bnode node , treenodecollection tnc)

193199

200class

count

201206

207class

bnode

217}

218 }

完全二叉樹與滿二叉樹與霍夫曼樹

去筆試了很多次,每次都有有關於二叉樹的題目,而且其中最多的是關於完全二叉樹,然而完全二叉樹在哥心中的形態一直很模糊,究其原因是我把完全二叉樹和滿二叉樹搞混了。其實滿二叉樹是完全二叉樹的特例,因為滿二叉樹已經滿了,而完全並不代表滿。所以形態你也應該想象出來了吧,滿指的是出了葉子節點外每個節點都有兩個孩...

二叉樹的C 實現演算法

鏈式儲存結構來表示二叉樹,每乙個二叉樹節點包含樹節點的值 樹的左孩子指標 樹的右孩子指標 class binode 那麼對於乙個二叉樹來說,只需要存放指向樹根節點的指標即可,另外還需要宣告二叉樹的一些功能,比如遍歷方法 求樹高等 bitree.h ifndef bitree h included d...

C 實現二叉樹

其中的 linkstack.h 和 linkqueue 分別在 以下兩篇博文裡 linkstack linkqueue include include linkstack.h include linkqueue.h using namespace std 定義節點 templatestruct no...