-
Notifications
You must be signed in to change notification settings - Fork 0
/
Huffman.cpp
105 lines (97 loc) · 2.95 KB
/
Huffman.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//
// Created by vsx on 2024/3/2.
//
#include "Huffman.h"
void Huffman::buildAndGenerate(const int* count,const int length, std::string*& codes) {
HuffmanTree root;
build(count,length,root);
root.levelOrderTraversal();
generate(root,codes,length);
}
void Huffman::build(const int *count,const int length, HuffmanTree &root) {
SqList<HTP> list;
for(int i=0;i<length;i++){
if(count[i]==0)
continue;
HTP temp;
temp.p=new HuffmanTree;
temp.p->id=i;
temp.p->weight=count[i];
temp.p->parent=nullptr;
temp.p->lchild=nullptr;
temp.p->rchild=nullptr;
list.insert(temp);
}
list.show();
while(list.getLength()>=2){
HTP lp,rp;//leftHTP,rightHTP
list.get(list.getLength()-2,lp);
list.get(list.getLength()-1,rp);
HTP temp;
temp.p=new HuffmanTree;
temp.p->id=-1;
temp.p->weight=lp.p->weight+rp.p->weight;
temp.p->parent=nullptr;
temp.p->lchild=lp.p;
temp.p->rchild=rp.p;
lp.p->parent=temp.p;
rp.p->parent=temp.p;
list.del(list.getLength()-2);
list.del(list.getLength()-1);
list.insert(temp);
}
HTP temp;
//对list中只有零个或一个元素的情况先进行判断
if(list.getLength()==0){
root.id=-1;
root.weight=0;
root.parent=nullptr;
root.lchild=nullptr;
root.rchild=nullptr;
}else{
list.get(0,temp);
if(temp.p->id!=-1){
root.id=-1;
root.weight=temp.p->weight;
root.parent=nullptr;
root.lchild=temp.p;
root.rchild=nullptr;
temp.p->parent=&root;
}else if(temp.p->id==-1){
root=*temp.p;
}
}
}
void Huffman::generate(const HuffmanTree &root, std::string*& codes, const int length) {
codes=new std::string[length];
postTraversal(&root,codes,length);
std::cout<<"-----------------------------------------------------------------"<<std::endl;
std::cout<<"Codes:"<<std::endl;
for(int i=0;i<length;i++){
if(codes[i]=="")
continue;
std::cout<<i<<":"<<codes[i]<<std::endl;
}
std::cout<<"-----------------------------------------------------------------"<<std::endl;
}
void Huffman::postTraversal(const HuffmanTree *rootp,std::string*& codes,const int length) {
if(rootp==nullptr)
return;
if(rootp->parent!=nullptr) {
if (rootp == rootp->parent->lchild) {
code.value.push_back('0');
} else if (rootp == rootp->parent->rchild) {
code.value.push_back('1');
} else {
std::cout << std::endl << "#HuffmanTreeError" << std::endl;
}
if (rootp->id != -1) {
codes[rootp->id] = code.value;
}
}
postTraversal(rootp->lchild, codes, length);
postTraversal(rootp->rchild, codes, length);
if (rootp->parent != nullptr) {
code.value.pop_back();
}
}