-
Notifications
You must be signed in to change notification settings - Fork 15
/
htree.c
63 lines (59 loc) · 1.93 KB
/
htree.c
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
/* ------------------- htree.c -------------------- */
#include "dflat.h"
#include "htree.h"
struct htree *ht;
int root;
int treect;
/* ------ build a Huffman tree from a frequency array ------ */
void buildtree(void)
{
int i;
treect = 256;
/* ---- preset node pointers to -1 ---- */
for (i = 0; i < treect; i++) {
ht[i].parent = -1;
ht[i].right = -1;
ht[i].left = -1;
}
/* ---- build the huffman tree ----- */
while (1) {
int h1 = -1, h2 = -1;
/* ---- find the two lowest frequencies ---- */
for (i = 0; i < treect; i++) {
if (i != h1) {
struct htree *htt = ht+i;
/* --- find a node without a parent --- */
if (htt->cnt > 0 && htt->parent == -1) {
/* ---- h1 & h2 -> lowest nodes ---- */
if (h1 == -1 || htt->cnt < ht[h1].cnt) {
if (h2 == -1 || ht[h1].cnt < ht[h2].cnt)
h2 = h1;
h1 = i;
}
else if (h2 == -1 || htt->cnt < ht[h2].cnt)
h2 = i;
}
}
}
/* --- if only h1 -> a node, that's the root --- */
if (h2 == -1) {
root = h1;
break;
}
/* --- combine two nodes and add one --- */
ht[h1].parent = treect;
ht[h2].parent = treect;
ht = realloc(ht, (treect+1) * sizeof(struct htree));
if (ht == NULL)
break;
/* --- the new node's frequency is the sum of the two
nodes with the lowest frequencies --- */
ht[treect].cnt = ht[h1].cnt + ht[h2].cnt;
/* - the new node points to the two that it combines */
ht[treect].right = h1;
ht[treect].left = h2;
/* --- the new node has no parent (yet) --- */
ht[treect].parent = -1;
treect++;
}
}