建立Huffman树的编码问题

Pollywog1983 2004-08-19 03:34:53
由于这个函数的定义变量很多,我看的时候思绪很混乱,希望有这方面的高手能给我解释一下这段程序:
int huft_build(b, n, s, d, e, t, m)
unsigned *b; /* code lengths in bits (all assumed <= BMAX) */
unsigned n; /* number of codes (assumed <= N_MAX) */
unsigned s; /* number of simple-valued codes (0..s-1) */
ush *d; /* list of base values for non-simple codes */
ush *e; /* list of extra bits for non-simple codes */
struct huft **t; /* result: starting table */
int *m; /* maximum lookup bits, returns actual */
/* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return zero on success, one if
the given code set is incomplete (the tables are still built in this
case), two if the input is invalid (all zero length codes or an
oversubscribed set of lengths), and three if not enough memory. */
{
unsigned a; /* counter for codes of length k */
unsigned c[BMAX+1]; /* bit length count table */
unsigned f; /* i repeats in table every f entries */
int g; /* maximum code length */
int h; /* table level */
register unsigned i; /* counter, current code */
register unsigned j; /* counter */
register int k; /* number of bits in current code */
int l; /* bits per table (returned in m) */
register unsigned *p; /* pointer into c[], b[], or v[] */
register struct huft *q; /* points to current table */
struct huft r; /* table entry for structure assignment */
struct huft *u[BMAX]; /* table stack */
unsigned v[N_MAX]; /* values in order of bit length */
register int w; /* bits before this table == (l * h) */
unsigned x[BMAX+1]; /* bit offsets, then code stack */
unsigned *xp; /* pointer into x */
int y; /* number of dummy codes added */
unsigned z; /* number of entries in current table */


/* Generate counts for each bit length */
memzero(c, sizeof(c));
p = b; i = n;
do {
Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"),
n-i, *p));
c[*p]++; /* assume all entries <= BMAX */
p++; /* Can't combine with above line (Solaris bug) */
} while (--i);
if (c[0] == n) /* null input--all zero length codes */
{
*t = (struct huft *)NULL;
*m = 0;
return 0;
}


/* Find minimum and maximum length, bound *m by those */
l = *m;
for (j = 1; j <= BMAX; j++)
if (c[j])
break;
k = j; /* minimum code length */
if ((unsigned)l < j)
l = j;
for (i = BMAX; i; i--)
if (c[i])
break;
g = i; /* maximum code length */
if ((unsigned)l > i)
l = i;
*m = l;


/* Adjust last length count to fill out codes, if needed */
for (y = 1 << j; j < i; j++, y <<= 1)
if ((y -= c[j]) < 0)
return 2; /* bad input: more codes than bits */
if ((y -= c[i]) < 0)
return 2;
c[i] += y;


/* Generate starting offsets into the value table for each length */
x[1] = j = 0;
p = c + 1; xp = x + 2;
while (--i) { /* note that i == g from above */
*xp++ = (j += *p++);
}


/* Make a table of values in order of bit lengths */
p = b; i = 0;
do {
if ((j = *p++) != 0)
v[x[j]++] = i;
} while (++i < n);
n = x[g]; /* set n to length of v */


/* Generate the Huffman codes and for each, make the table entries */
x[0] = i = 0; /* first Huffman code is zero */
p = v; /* grab values in bit order */
h = -1; /* no tables yet--level -1 */
w = -l; /* bits decoded == (l * h) */
u[0] = (struct huft *)NULL; /* just to keep compilers happy */
q = (struct huft *)NULL; /* ditto */
z = 0; /* ditto */

/* go through the bit lengths (k already is bits in shortest code) */
for (; k <= g; k++)
{
a = c[k];
while (a--)
{
/* here i is the Huffman code of length k bits for value *p */
/* make tables up to required level */
while (k > w + l)
{
h++;
w += l; /* previous table always l bits */

/* compute minimum size table less than or equal to l bits */
z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */
xp = c + k;
if (j < z)
while (++j < z) /* try smaller tables up to z bits */
{
if ((f <<= 1) <= *++xp)
break; /* enough codes to use up j bits */
f -= *xp; /* else deduct codes from patterns */
}
}
z = 1 << j; /* table entries for j-bit table */

/* allocate and link in new table */
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
(struct huft *)NULL)
{
if (h)
huft_free(u[0]);
return 3; /* not enough memory */
}
hufts += z + 1; /* track memory usage */
*t = q + 1; /* link to list for huft_free() */
*(t = &(q->v.t)) = (struct huft *)NULL;
u[h] = ++q; /* table starts after link */

/* connect to last table, if there is one */
if (h)
{
x[h] = i; /* save pattern for backing up */
r.b = (uch)l; /* bits to dump before this table */
r.e = (uch)(16 + j); /* bits in this table */
r.v.t = q; /* pointer to this table */
j = i >> (w - l); /* (get around Turbo C bug) */
u[h-1][j] = r; /* connect to last table */
}
}

/* set up table entry in r */
r.b = (uch)(k - w);
if (p >= v + n)
r.e = 99; /* out of values--invalid code */
else if (*p < s)
{
r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */
r.v.n = (ush)(*p); /* simple code is just the value */
p++; /* one compiler does not like *p++ */
}
else
{
r.e = (uch)e[*p - s]; /* non-simple--look up in lists */
r.v.n = d[*p++ - s];
}

/* fill code-like entries with r */
f = 1 << (k - w);
for (j = i >> w; j < z; j += f)
q[j] = r;

/* backwards increment the k-bit code i */
for (j = 1 << (k - 1); i & j; j >>= 1)
i ^= j;
i ^= j;

/* backup over finished tables */
while ((i & ((1 << w) - 1)) != x[h])
{
h--; /* don't need to update q */
w -= l;
}
}
}


/* Return true (1) if we were given an incomplete table */
return y != 0 && g != 1;
}
...全文
324 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Pollywog1983 2004-08-20
  • 打赏
  • 举报
回复
但是这一段程序和一般的Huffman树的建立方法有所不同,看的时候有很多关键性的地方都不是很懂!
WYlslrt 2004-08-20
  • 打赏
  • 举报
回复
那你知道建立哈夫曼树的方法吗,不知道的话去看数据结构任何一本书上都会介绍的。
如果知道的话,我想不难看懂。
Pollywog1983 2004-08-19
  • 打赏
  • 举报
回复
看来是程序给的太长了,其实这段程序就是一个建立Huffman树的函数。
Pollywog1983 2004-08-19
  • 打赏
  • 举报
回复
没有高手接触过这方面吗?
Pollywog1983 2004-08-19
  • 打赏
  • 举报
回复
尤其希望高手能告诉我函数中每个参数所代表的意义!谢谢!

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧