• 赫夫曼树


    #include <conio.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    typedef struct{
        int weight;
        int parent, lchild,rchild;
    }HTNode, *HuffmanTree;
    
    typedef char ** HuffmanCode;
    
    void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n);    //w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC
    void select(const HuffmanTree &HT, int n, int &s1, int &s2);    //选择parent为0且weiht最小的两个结点,其序号分别为s1,s2
    
    int main(){
        HuffmanTree HT;
        HuffmanCode HC;
        int i;
        const int n = 8;
        int weight[n] = {5,29,7,8,14,23,3,11};
    
        HuffmanCoding(HT, HC, weight, n);
        for(i=1; i<=n; i++)
            printf("%d %s\n",HT[i].weight, HC[i]);
    
        return 0;
    }
    
    void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){    //w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC
        int i,m,s1,s2;
    //    HuffmanTree p;
        int start,f,c;//start指向当前编码位置,f为parent结点序号,c为当前的结点序号
    
        if(n <= 1)    return ;
        m = 2*n-1;
        HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));    //0号单元未用
        memset(HT,0,(m+1)*sizeof(HTNode));
    
        for(i=1; i<=n; ++i, ++w)    HT[i].weight = *w;
        for(i = n+1; i<=m; i++){    //建赫夫曼树
            select(HT, i-1, s1, s2);
            HT[s1].parent = i;    HT[s2].parent = i;
            HT[i].lchild = s1;    HT[i].rchild = s2;
            HT[i].weight = HT[s1].weight + HT[s2].weight;
        }
        
        //求赫夫曼编码
        HC = (HuffmanCode)malloc((n+1) * sizeof(char *));    //分配n个字符编码的头指针向量
        char *cd = (char *)malloc(n * sizeof(char));    //分配求编码的工作空间
        cd[n-1] = '\0';//编码结束符
        for(i=1; i<=n; i++){    //逐个字符求赫夫曼编码
            start = n-1;//编码结束符位置
            for(c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent)    //从叶子到根你想求编码
                if(HT[f].lchild == c)    cd[--start] = '0';
                else    cd[--start] = '1';
                HC[i] = (char *)malloc((n-start) * sizeof(char));    //为第i个字符编码分配空间
                strcpy(HC[i], &cd[start]);    //从cd复制编码到HC
        }
        free(cd); 
    }
    
    void select(const HuffmanTree &HT, int n, int &s1, int &s2){    //选择parent为0且weiht最小的两个结点,其序号分别为s1,s2
        if(n < 1) return ;
        int i,min1,min2;    //min1为最小,min2为第二小
        int ic=0;    //主要用来处理初始时的情况 和 当!=0 的数仅剩2个的情况
        for(i=1; i<=n; i++){
            if(HT[i].parent != 0)    continue;
            if(ic == 0){
                min1 = i; min2 = i;    ic++;
            }
            else if(ic == 1){
                if(HT[min1].weight > HT[i].weight){
                    min2 = min1;    min1 = i;    ic++;
                }
                else{
                    min2 = i;    ic++;
                }
            }
            else{
                if(HT[min1].weight > HT[i].weight){
                        min2 = min1;
                        min1 = i;
                }
                else if(HT[min2].weight > HT[i].weight)    min2= i;
                else if(HT[min2].weight == HT[i].weight && min1 == min2)    min2 = i;
            }
        }
        s1 = min1;    s2 = min2;
    }
  • 相关阅读:
    Java面试
    md5加密
    CSS3画苹果手机
    CSS3的表格布局 文字居中 圆角
    CSS3的新特性 行内盒子before和after
    DIV CSS Sprites精灵 CSS图像拼合 CSS背景贴图定位教程案例
    DAY30
    DedeCMS织梦修改数据库密码和数据库连接失败解决方法
    学习计划
    【原】雅虎前端优化的35条军规
  • 原文地址:https://www.cnblogs.com/tanhehe/p/2883520.html
Copyright © 2020-2023  润新知