哈夫曼二叉树源码

原创 2003年05月26日 13:50:00

哈夫曼二叉树源码:

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

——数据结构

#include <string.h><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

#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

 

哈夫曼(最优二叉树)

最优二叉树: 定义: 路径:数的路径就是从书中的一个节点到树中的另一个节点的分支的个数长度,路径上的分支数目我们称之为长度 树的路径长度:从树根到每一个节点的长度之和(完全二叉树是一种树的路径最...
  • ltyqljhwcm
  • ltyqljhwcm
  • 2016年09月08日 16:15
  • 1093

Huffman树(二叉树)

算法思想:(二叉树) 给定n个权值构造一个huffman树,将n个权值节点从小到大进行排列,建立一个单链表,然后每次选择表头最小的两个节点,把他们作为一个新节点的儿子,头节点的权值为左右儿子权值之和...
  • xinshoushanglu2333
  • xinshoushanglu2333
  • 2015年12月14日 19:35
  • 253

数据结构----二叉树----哈夫曼编码

1、阅读本文前,读者要对二叉树、贪心、优先队列等知识有一定了解。 2、此题比较坑,阅读之前请做好心理准备。 一、了解基本概念 1、二叉树、二叉树的构造方法、二叉树的各种遍历(不用说了吧.......
  • C20180602_csq
  • C20180602_csq
  • 2017年01月20日 21:21
  • 510

【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算

1、树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基...
  • swj524152416
  • swj524152416
  • 2016年10月31日 10:09
  • 2628

二叉树实现哈夫曼码

最近完成一个数据结构的作业,哈夫曼编码,实现了 1.查看字母的哈夫曼码 2.哈夫曼码转文字 3.文字转哈夫曼码 这几个功能 哈夫曼码主要用于压缩编码,将字符用二进制(0,1)编码代替,能过...
  • yk_ee
  • yk_ee
  • 2016年03月31日 00:07
  • 262

Huffman对文件编码和解码

Huffman编码和解码
  • jsjliuyun
  • jsjliuyun
  • 2014年11月24日 16:30
  • 1843

简单的C语言二叉树的实现代码

#include #include #include #include typedef int ElemType; typedef struct Node { ElemT...
  • qq_21431111
  • qq_21431111
  • 2014年10月04日 20:40
  • 1607

Huffman tree(赫夫曼树、霍夫曼树、哈夫曼树、最优二叉树)

Huffman tree(赫夫曼树、霍夫曼树、哈夫曼树、最优二叉树)flyfish 2015-8-1Huffman tree因为翻译不同所以有其他的名字 赫夫曼树、霍夫曼树、哈夫曼树 定义引用自严蔚...
  • flyfish1986
  • flyfish1986
  • 2015年08月01日 22:37
  • 2686

数据结构--我的哈夫曼编译系统

哈夫曼编译系统
  • fengsigaoju
  • fengsigaoju
  • 2015年10月23日 01:13
  • 844

【二叉树】哈夫曼定理与原理

1、从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径的长度。 2、树的路径长度是从树根到每一结点的路径长度之和。 3、树的带权路径长度(WPL)是树中所有叶子结...
  • Wonder233
  • Wonder233
  • 2018年01月16日 09:38
  • 36
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:哈夫曼二叉树源码
举报原因:
原因补充:

(最多只允许输入30个字)