分享
 
 
 

哈夫曼二叉树源码

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

哈夫曼二叉树源码:

给定一个字符串,根据统计字符串中各个字符出现的频率对字符进行哈夫曼编码,然后对原字符串进行编码,并输出编码后的内容

——数据结构

#include <string.h>

#define MAX_NODE 1024

#define MAX_WEIGHT 4096

typedef struct HaffmanTreeNode {

char ch, code[15];

int weight;

int parent, lchild, rchild;

} HTNode, *HaTree;

typedef struct {

HTNode arr[MAX_NODE];

int total;

} HTree;

/* 统计字符出现的频率 */

int statistic_char(char *text, HTree *t){

int i, j;

int text_len = strlen(text);

t->total = 0;

for (i=0; i<text_len; i++) {

for (j=0; j<t->total; j++) if (t->arr[j].ch == text[i]){

t->arr[j].weight ++;

break;

}

if (j==t->total) {

t->arr[t->total].ch = text[i];

t->arr[t->total].weight = 1;

t->total ++;

}

}

printf("char frequence\n");

for (i=0; i<t->total; i++)

printf("'%c' %d\n", t->arr[i].ch, t->arr[i].weight);

printf("\n");

return t->total;

}

int create_htree(HTree *t)

{

int i;

int total_node = t->total * 2 - 1;

int min1, min2; /* 权最小的两个结点 */

int min1_i, min2_i; /* 权最小结点对应的编号 */

int leaves = t->total;

for (i=0; i<leaves; i++) {

t->arr[i].parent = -1;

t->arr[i].rchild = -1;

t->arr[i].lchild = -1;

}

while (t->total < total_node) {

min1 = min2 = MAX_WEIGHT;

for (i=0; i<t->total; i++) { /* 对每一个结点 */

if (t->arr[i].parent == -1 /* 结点没有被合并 */

&& t->arr[i].weight < min2) { /* 结点的权比最小权小 */

if (t->arr[i].weight < min1) { /* 如果它比最小的结点还小 */

min2_i = min1_i; min2 = min1;

min1_i = i; min1 = t->arr[i].weight;

}

else

{

min2_i = i; min2 = t->arr[i].weight;

}

}

}

t->arr[t->total].weight = min1 + min2;

t->arr[t->total].parent = -1;

t->arr[t->total].lchild = min1_i;

t->arr[t->total].rchild = min2_i;

t->arr[min1_i].parent = t->total;

t->arr[min2_i].parent = t->total;

t->arr[t->total].ch = ' ';

t->total ++;

}

return 0;

}

/* 对哈夫曼树进行编码 */

void coding(HTree *t, int head_i, char *code)

{

if ( head_i == -1) return;

if (t->arr[head_i].lchild == -1 && t->arr[head_i].rchild == -1) {

strcpy(t->arr[head_i].code, code);

printf("'%c': %s\n", t->arr[head_i].ch, t->arr[head_i].code);

}

else {

int len = strlen(code);

strcat(code, "0");

coding(t, t->arr[head_i].lchild, code);

code[len] = '1';

coding(t, t->arr[head_i].rchild, code);

code[len] = '\0';

}

}

/* 中序打印树 */

void print_htree_ldr(HTree *t, int head_i, int deep, int* path)

{

int i;

if (head_i == -1) return;

path[deep] = 0;

print_htree_ldr(t, t->arr[head_i].lchild, deep + 1, path);

if (deep) printf(" ");

for (i=1; i<deep; i++) printf("%s", path[i]==path[i-1]?" ":"│ ");

int dir = path[i]==path[i-1];

if ( t->arr[head_i].lchild == -1 && t->arr[head_i].rchild == -1)

printf("%s── %d '%c'\n", dir? "┌":"└",

t->arr[head_i].weight, t->arr[head_i].ch);

else if (head_i != t->total-1)

printf("%s─%02d┤\n", dir? "┌":"└"", t->arr[head_i].weight);

else

printf(" %02d┤\n", t->arr[head_i].weight);

path[deep] = 1;

print_htree_ldr(t, t->arr[head_i].rchild, deep + 1, path);

}

/* 对字符进行编码 */

void code_string(char *text, HTree *t)

{

int i, j, text_len = strlen(text);

int n = 0;

for (i=0; i<text_len; i++) {

char ch = text[i];

for (j=0; j<t->total; j++) if (ch == t->arr[j].ch) {

printf("%s ", t->arr[j].code);

n += strlen(t->arr[j].code);

break;

}

}

printf("\n%d chars, Total len = %d\n", text_len, n);

}

int main(int argc, char* argv[])

{

HTree t;

char text[128]="ABAAAAEEEAAACCCCAAAACCDEA";

char code[128] = "";

int path[16]={0};

statistic_char(text, &t);

create_htree(&t);

print_htree_ldr(&t, t.total-1, 0, path);

coding(&t, t.total-1, code);

code_string(text, &t);

return 0;

}

输出结果:

char frequence

'A' 13

'B' 1

'E' 4

'C' 6

'D' 1

┌── 6 'C'

┌─12┤

│ │ ┌── 1 'B'

│ │ ┌─02┤

│ │ │ └── 1 'D'

│ └─06┤

│ └── 4 'E'

25┤

└── 13 'A'

'C': 00

'B': 0100

'D': 0101

'E': 011

'A': 1

1 0100 1 1 1 1 011 011 011 1 1 1 00 00 00 00 1 1 1 1 00 00 0101 011 1

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有