惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Jina AI
Jina AI
P
Palo Alto Networks Blog
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
Blog — PlanetScale
Blog — PlanetScale
S
Schneier on Security
V
Vulnerabilities – Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
雷峰网
雷峰网
T
Tenable Blog
人人都是产品经理
人人都是产品经理
T
Tor Project blog
C
Cyber Attacks, Cyber Crime and Cyber Security
AWS News Blog
AWS News Blog
Microsoft Security Blog
Microsoft Security Blog
J
Java Code Geeks
Scott Helme
Scott Helme
SecWiki News
SecWiki News
C
CERT Recently Published Vulnerability Notes
Recorded Future
Recorded Future
I
InfoQ
Security Archives - TechRepublic
Security Archives - TechRepublic
Help Net Security
Help Net Security
Cloudbric
Cloudbric
C
Check Point Blog
Engineering at Meta
Engineering at Meta
TaoSecurity Blog
TaoSecurity Blog
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
N
News and Events Feed by Topic
云风的 BLOG
云风的 BLOG
MyScale Blog
MyScale Blog
腾讯CDC
量子位
Application and Cybersecurity Blog
Application and Cybersecurity Blog
K
Kaspersky official blog
Vercel News
Vercel News
F
Full Disclosure
T
Troy Hunt's Blog
Forbes - Security
Forbes - Security
S
Security @ Cisco Blogs

博客园 - I love I think

Tomcat 配置集锦 eclipse+tomcat python的对象与名字绑定(转贴,此文甚好) 单引号、双引号和三双引号的区别 - I love I think 这几天一直在看Latex,试着排版了一份试卷。 开机即打开Numlock - I love I think Keep track of own postings using Summary Highlighting (Submitted by dzimmerm on Sun, 12/28/2003 - 18:31. ) 新闻组上看到一篇关于linux内核编译的文章,留待日后参考。 调整显示屏幕偏移和刷新频率[zt] The best way to predict future is to invent it.------Alan Kay 数学学科分类标准 KMP算法 有趣的东西太多了。 nvidia驱动安装 linux内核源码目录结构 Linux打印介绍【转贴】 矩阵的相似对角化到底有什么用?该不会是纯粹的理论吧? 宫崎骏的动画片真有意思啊。 elisp1
哈夫曼树(调试没通过,郁闷)
I love I think · 2005-01-17 · via 博客园 - I love I think

#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