-
Notifications
You must be signed in to change notification settings - Fork 0
/
huffmancode.cpp
166 lines (138 loc) · 4.58 KB
/
huffmancode.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
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
//Sunny Mei 0599
#include <cstddef>
#include "huffman.h"
// ---------------------------------------------------------------------------------------------
// Huffman code related
// ---------------------------------------------------------------------------------------------
// The HuffmanNode constructor for leaf nodes
HuffmanNode::HuffmanNode(char character, int frequency) {
// TODO
this->character = character;
this->frequency = frequency;
this->isLeaf = 1;
this->left = NULL;
this->right = NULL;
}
// The HuffmanNode constructor for internal nodes
HuffmanNode::HuffmanNode(int frequency, HuffmanNode *left, HuffmanNode *right) {
// TODO
this->frequency = frequency;
this->left = left;
this->right = right;
this->isLeaf = 0;
}
/*
Creates an array of HuffmanNodes (more specifically, pointers to HuffmanNodes)
based on the given character-frequency pairs.
characters: an array of char
frequencies: an array of int
length: the length of characters and frequencies arrays
returns: an array of HuffmanNode*
Note: For 0 <= i < length, the frequency of the character characters[i]
is found at frequencies[i].
*/
HuffmanNode **genHuffmanNodes(char *characters, int *frequencies, int length) {
HuffmanNode **array = new HuffmanNode *[length];
for (int i = 0; i < length; i++)
{
HuffmanNode *index = new HuffmanNode(characters[i], frequencies[i]);
array[i] = index;
}
return array;
}
/*
Creates the Huffman tree reusing the given HuffmanNodes.
nodes: an array of HuffmanNode*
length: the length of nodes array
returns: the pointer to the root of the huffman tree
*/
HuffmanNode *genHuffmanTree(HuffmanNode **nodes, int length) {
MinHeap min = MinHeap(nodes, length);//create the array with minHeap constructor
while (min.heapSize > 1)//it will run until the array has size one
{
HuffmanNode *L, *R;//we make the nodes for left and right
L = min.extractMin();//we extract the min from the heap and assign it to left
R = min.extractMin();//we do the same for the right
HuffmanNode *internal = new HuffmanNode(L->frequency + R->frequency, L, R);//we create an internal node with the sum of the frequency left and right.
//we also assign left and right to be child of internal
min.insert(internal);//we insert the internal node back into the heap
}
return min.extractMin();//we extract the min but since we only got one element left in the array, this should be the root.
}
// ---------------------------------------------------------------------------------------------
// Min heap related
// ---------------------------------------------------------------------------------------------
// Helper functions for heap
int left(int index) {
return (index + 1) * 2 - 1;
}
int right(int index) {
return (index + 1) * 2;
}
int parent(int index) {
return (index + 1) / 2 - 1;
}
// MinHeap constructor
MinHeap::MinHeap(HuffmanNode **nodes, int length) {
heapSize = length;
this->heapNodes = new HuffmanNode *[length];
for (int i = 0; i < length; i++)
this->heapNodes[i] = nodes[i];
buildMinHeap();
}
// Exchanges the HuffmanNode pointers at the given indices of heapNodes array
void MinHeap::exchange(int firstIndex, int secondIndex) {
// TODO
HuffmanNode * temp;
temp = heapNodes[firstIndex];
heapNodes[firstIndex] = heapNodes[secondIndex];
heapNodes[secondIndex] = temp;
}
// Applies the minHeapify algorithm starting from the given index
void MinHeap::minHeapify(int index) {
// TODO
int smallest = index;
int size = heapSize;
if (left(index) < size && heapNodes[left(index)]->frequency < heapNodes[smallest]->frequency)
{
smallest = left(index);
}
if (right(index) < size && heapNodes[right(index)]->frequency < heapNodes[smallest]->frequency)
{
smallest = right(index);
}
if (smallest != index)
{
exchange(smallest, index);
minHeapify(smallest);
}
}
// Converts the heapNodes array into a heap
void MinHeap::buildMinHeap() {
for (int i = heapSize / 2 - 1; i >= 0; i--)
minHeapify(i);
}
// Removes the minimum element from the heap and returns it
HuffmanNode *MinHeap::extractMin() {
// TODO
if (heapSize < 1)
{
return NULL;
}
HuffmanNode *temp;
temp = heapNodes[0];
heapNodes[0] = heapNodes[heapSize - 1];
heapSize--;
minHeapify(0);
return temp;
}
// Inserts a new HuffmanNode to the heap
void MinHeap::insert(HuffmanNode *node) {
heapSize++;
int i = heapSize - 1;
heapNodes[i] = node;
while (i > 0 && *heapNodes[parent(i)] > *heapNodes[i]) {
exchange(i, parent(i));
i = parent(i);
}
}