-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhuffman.h
252 lines (207 loc) · 5.67 KB
/
huffman.h
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#ifndef __HUFFMAN_H__
#define __HUFFMAN_H__
#include <string>
#include <queue>
#include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
#include <chrono>
#include <locale>
//#define _DEBUG_
typedef unsigned char CHAR;
typedef unsigned int UINT;
using namespace std;
using namespace std::chrono;
typedef std::ratio<1l, 1000000000000l> pico;
typedef duration<long long, pico> picoseconds;
typedef std::ratio<1l, 1000000l> micro;
typedef duration<long long, micro> microseconds;
#define ExtndAscii_len 256
struct huffman_node
{
int id; //character
int freq; //frequency of the character
UINT code; //huffman code for the character
CHAR code_length;
huffman_node* left;
huffman_node* right;
huffman_node()
{
left = right = NULL;
freq = 0;
code_length = 0;
}
bool operator<(const huffman_node& a) const
{
return freq >a.freq;
}
};
struct sgh_node
{
int id;
UINT code;
CHAR code_length;
sgh_node* left;
sgh_node* right;
bool is_subtree_root;
bool is_symbol_node;
bool is_last_symbol; // Last symbol means char with least freq in sgh tree
int freq;
bool is_entered_in_Index;
bool is_entered_in_symbol;
sgh_node()
{
id = -1;
left = right = NULL;
is_subtree_root = false;
is_symbol_node = false;
is_last_symbol = false;
code = '\0';
freq = 0;
is_entered_in_Index = false;
is_entered_in_symbol = false;
code_length = 0;
}
sgh_node(CHAR code)
{
id = -1;
this->code = code;
left = right = NULL;
is_subtree_root = false;
is_symbol_node = false;
is_last_symbol = false;
freq = 0;
code_length = 0;
is_entered_in_Index = false;
is_entered_in_symbol = false;
}
bool operator<(const sgh_node& a) const
{
return freq > a.freq;
}
};
struct struct_index
{
int starting_address; //starting address in symbol table i.e decimal value of code mentioned below
int depth_subtree;
struct_index(int starting_address,int depth_subtree)
{
this->starting_address = starting_address;
this->depth_subtree = depth_subtree;
}
void display()
{
cout<<" Starting address in Symbol Table is "<<starting_address<<" and depth of subtree is "<<depth_subtree<<endl;
}
};
struct struct_symbol_entry
{
int id;
CHAR code_length;
bool isMultientryElement;
bool isfirstEntry; // only valid if Duplicated
struct_symbol_entry(int id, CHAR code_length,bool isFirstEntry, bool isMultientryElement = false)
{
this->id = id;
this->code_length = code_length;
this->isMultientryElement = isMultientryElement;
this->isfirstEntry = isfirstEntry;
}
};
typedef huffman_node* node_ptr;
#define LAST(k,n) ((k) & ((1<<(n))-1))
#define MID(k,m,n) LAST((k)>>(m),((n)-(m)))
class huffman
{
protected:
enum CHILD_SIDE{LEFT,RIGHT};
node_ptr node_array[ExtndAscii_len];
sgh_node sgh_node_array[ExtndAscii_len];
vector<struct_index> index_array;
vector<struct_symbol_entry> symbol_array;
fstream in_file, out_file;
node_ptr child, parent, root;
sgh_node *sghRoot = new sgh_node();
CHAR id;
string in_file_name, out_file_name;
int MAX_LENGTH_SGH_CODE = 0;
UINT sghCharOutput = 0;
CHAR sghLastCharLen = 0;
class compare
{//a object funtion to set comparing rule of priority queue
public:
int operator()(const node_ptr& c1, const node_ptr& c2) const
{
if( c1->freq > c2->freq) return 1;
else if( c1->freq < c2->freq) return 0;
else return -1;
}
};
class compareFreq_Code
{
public:
bool operator()(const huffman_node& a, const huffman_node& b) const
{
if(a.freq != b.freq)
{
return (a.freq > b.freq);
}
else
return (a.code_length < b.code_length);
}
};
priority_queue<node_ptr, vector<node_ptr>, compare> pq; //priority queue of frequency from high to low
void create_node_array();
void traverse(node_ptr, UINT,CHAR); //traverse the huffman tree and get huffman code for a character
bool isIndexArrayElementExist(int );
void createSghNode(sgh_node**, UINT,CHAR, CHILD_SIDE);
int removeSubtreeStatusFromLastSubtree(sgh_node*);
int depth(sgh_node* );
void sghCharCount();
UINT countNodes(sgh_node* root);
int findHeightOfthisNode(sgh_node*,sgh_node *);
int getLevelUtil(sgh_node *,UINT, int);
bool isComplete (sgh_node* root, UINT, UINT);
void insertIntoSymbolArray(sgh_node*, bool,sgh_node *);
void traverseSGHForSymbolArray(sgh_node*);
void traverseSGHForIndexArray(sgh_node*);
int returnFirstIndexFromSymbolArray(int);
sgh_node* findleftmostSymbol(sgh_node*);
bool checkPrefixness();
bool isSubtreeAlreadymade(UINT,CHAR, vector<sgh_node> );
void print2DUtil_sgh(sgh_node *, int );
void print2DUtil_huffman(huffman_node *, int );
void print2D_huffman(huffman_node *);
void print2D_sgh(sgh_node *);
CHAR findCodeLength(UINT);
void printBinary(UINT, CHAR);
void decodeSghCode(UINT,CHAR &, UINT);
public:
~huffman();
UINT sghCharCountDeco = 0;
UINT sghCharCountEnco = -1;
UINT huffCharCountEnco = 0;
UINT huffCharCountDeco = 1;
void deleteHuffTree(huffman_node* node);
void deleteSghTree(sgh_node* node);
void makeHugeRandomFile(string);
void setInputFile(string);
void create_pq();
void create_huffman_tree();
void calculate_huffman_codes();
void huffEncoding();
void huffDecoding();
void huffCompareText();
void generateSGHCode();
void build_sgh_tree();
void create_symbol_array();
void create_index_array();
void sghEncoding();
void sghDecoding();
void sghCompareText();
void printSymbolArray();
void printIndexArray();
};
#endif