mirror of
https://github.com/reactos/reactos.git
synced 2024-08-16 16:39:08 +00:00
65 lines
1.9 KiB
C
65 lines
1.9 KiB
C
/* ------------------- 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++;
|
|
}
|
|
}
|
|
|