哈夫曼编码

来源:互联网 发布:网络兼职干什么好 编辑:程序博客网 时间:2024/05/17 09:47
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
 
#define MAX_CODE  8  

class HNode{
public:
    char c;  //字符   
    int weight; //权重   
    int lchild; //左孩子节点位置  
    int rchild; //右孩子节点位置  
    char code[MAX_CODE]; //得到的编码
    HNode(){  
        weight = -1;  
        lchild = -1;  
        rchild = -1;  
    }
};
 
 
//快速排序  
template<class T>  
void Swap(T &a, T &b){  
    T t = a;  
    a = b;  
    b = t;  
}  
 
 
int Partition(HNode* a,int p,int r){  
    if( !a || ( p > r ) ){  
        printf("ERROR: a cant be null\n");  
        exit(-1);  
    }  
    int i = p;  
    int j = r;  
    HNode x = a[p];  
    while( true ){  
        while( a[i].weight <= x.weight && ( i < r ) ) i++;  
        while( a[j].weight > x.weight ) j--;  
        if( i >= j ) break;  
        Swap(a[i], a[j]);  
    }  
    a[p] = a[j];  
    a[j] = x;  
    return j;  
}  
void QuickSort_ByWeight(HNode* a,int p,int r){  
    if( !a || ( p > r ) ){  
        return ;  
    }  
    int q = Partition(a, p, r);  
    QuickSort_ByWeight(a, p, q-1);  
    QuickSort_ByWeight(a, q+1, r);  
 
}  
 
 
void makeCode(HNode* nodes,int index,int parentIndex,const char b = 'l'){ //nodes最后一个节点的下标是2*num-1  
 
 
    if ( parentIndex == -1 )    {  
        nodes[index].code[0] = '\0';  
    }else{  
        if ( b == 'l' ) //假如是父亲的左儿子   
        {    
            strcpy(nodes[index].code , nodes[ parentIndex ].code);  
            strcat(nodes[ index ].code,"0");  
        }   
        if ( b == 'r' ) //假如是父亲的左儿子   
        {  
            strcpy(nodes[index].code , nodes[ parentIndex ].code);  
            strcat(nodes[index].code,"1");  
        }  
    }  
 
    if ( nodes[index].lchild != -1 )    {  
        makeCode(nodes, nodes[index].lchild, index, 'l');  
    }  
    if ( nodes[index].rchild != -1 )    {  
        makeCode(nodes, nodes[index].rchild, index, 'r' );  
    }  
}  
 
 
  //nodes指向的数组大小必须是超过 2*num - 1的;
   //num 是字符数目   
void createHTree(HNode* nodes,int num){  
    int left = 0;  
    int right = num-1;  
    for (int i = 0; i < num-1 && ((right+1) <= 2*num-1) ; i++)  
    {  
        QuickSort_ByWeight(nodes, left, right );  
        nodes[right+1].c = '#';             // 表示非叶子节点
        nodes[right+1].weight = nodes[left].weight + nodes[left+1].weight;  
        nodes[right+1].lchild = left;  
        nodes[right+1].rchild = left+1;  
 
        left += 2;  
        right ++;  
    }  
 
    makeCode(nodes, 2*num-2, -1);  
}  
   
void main(){    
    int num = 6;  
    int sizeOfNodes = 11;//2*num-1;  
    HNode *nodes = new HNode[sizeOfNodes];

    nodes[0].c = 'a';  
    nodes[0].weight = 37;  
         
    nodes[1].c = 'b';  
    nodes[1].weight = 13;  
 
    nodes[2].c = 'c';  
    nodes[2].weight = 22;  
 
    nodes[3].c = 'd';  
    nodes[3].weight = 16;   
 
    nodes[4].c = 'e';  
    nodes[4].weight = 9;   
 
    nodes[5].c = 'f';  
    nodes[5].weight = 8;    
 
    createHTree(nodes, num);  
 
    for (int i = 0; i < 2*num-1 ; i++)  
    {  
        if (nodes[i].c != '#' )  
        {printf("%c : %s\n",nodes[i].c,nodes[i].code);  
        }  
    }
    delete nodes;
}

原创粉丝点击