哈夫曼二叉树源码

哈夫曼二叉树源码:

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

——数据结构

#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

 

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 2
    评论
文章作者写的matlab源代码,该文章发表在Digital Signal Processing: Ke-Kun Huang , Hui Liu, Chuan-Xian Ren, Yu-Feng Yu and Zhao-Rong Lai. Remote sensing image compression based on binary tree and optimized truncation. Digital Signal Processing, vol. 64, pp. 96-106, 2017. (http://dx.doi.org/10.1016/j.dsp.2017.02.008) 遥感图像数据非常广泛,因此需要通过空间设备上的低复杂度算法进行压缩。具有自适应扫描顺序(BTCA)的二叉树编码是一个的有效算法。然而,对于大规模遥感图像,BTCA需要大量的内存,而且不能随机存取。在本文中,我们提出了一种基于BTCA的新的编码方法。小波图像首先划分为几个块,并由BTCA单独编码的。根据BTCA的属性,仔细选择每个块的有效截断点,以优化速率失真的比例,从而获得更高的压缩比、更低的内存要求和随机访问性能。由于没有任何熵编码,所提出的方法简单快速,非常适合于空间设备。对三个遥感图像集进行实验,结果表明它可以显着提高PSNR、SSIM和VIF,以及主观视觉体验。 The remote sensing image data is so vast that it requires compression by low-complexity algorithm on space-borne equipment. Binary tree coding with adaptive scanning order (BTCA) is an effective algorithm for the mission. However, for large-scale remote sensing images, BTCA requires a lot of memory, and does not provide random access property. In this paper, we propose a new coding method based on BTCA and optimize truncation. The wavelet image is first divided into several blocks which are encoded individually by BTCA. According the property of BTCA, we select the valid truncation points for each block carefully to optimize the ratio of rate-distortion, so that a higher compression ratio, lower memory requirement and random access property are attained. Without any entropy coding, the proposed method is simple and fast, which is very suitable for space-borne equipment. Experiments are conducted on three remote sensing image sets, and the results show that it can significantly improve PSNR, SSIM and VIF, as well as subjective visual experience.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

eion

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值