知道有的人比較懶,直接貼全部**.一開始一次性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.由於二叉樹的性質,將使用率低的先加入樹,使用率高的後加入作為使用率低的節點的父節點的兄弟節點(因為有值的節點必須是葉結點).從最底下向上構建
二叉樹.
1using
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...