Huffman Code

#include
#include
#include
#include 
#define UNCONSTRUCTED -1 //表示结点没有构建树
using namespace std;
/**哈夫曼树结点结构*/
struct HTNode
{
    int weight;//结点权重
    int parent, left, right;//父结点、左孩子、右孩子在数组中的位置下标
};

/**选择最小和次小结点*/
void selectMin(HTNode * HTArray,int k,int & minIndex1,int & minIndex2);
/**创建哈夫曼树*/
void createHuffmanTree(HTNode * HTArray,int * weightArray,int leafNum);
/**打印哈夫曼树*/
void printHufTree(HTNode * treeArray,int leafNum);
/**哈夫曼编码*/
void huffmanCoding(HTNode * HTArray,char * code[],int leafNum);
/**打印哈夫曼编码*/
void printCode(char * code[],char * data,int leafNum);
/**求WPL*/
int GetWPL(HTNode * HTArray,char * code[],int leafNum); 

int main()
{
    //叶子结点个数
    int leafNum=4;
    //权值数组和字符数组

    //测试数据1 ppt 13页
    //int w[4] = {2, 4, 5, 3};
    //ar data[leafNum]={'A','B','C','D'};

    //测试数据2 ppt 22页
    //int w[4] = {7, 5, 2, 4};

    //测试数据3 ppt 21页
    //leafNum=7;int w[7]={9, 11, 5, 7, 8, 2, 3};
    //ar data[leafNum]={'A','B','C','D','E','F','G'};

    //作业题测试数据
    leafNum=7;
    //int w[7]= {5,2,9,11,8,3,7};
    int w[7]={9,11,5,7,8,2,3};
    char data[7]= {'A','B','C','D','E','F','G'};

    //哈夫曼树数组
    HTNode * HTArray=new HTNode[leafNum*2-1];
    //创建哈夫曼树
    createHuffmanTree(HTArray,w,leafNum);

    //打印哈夫曼树
    printHufTree(HTArray,leafNum);

    //存放哈夫曼编码的二维数组
    char  *code[leafNum];
    //*code=new char[leafNum*leafNum];
    //char code[leafNum][leafNum];
    //进行编码
    //打印编码结果
    huffmanCoding(HTArray,code,leafNum);
    printCode(code,data,leafNum);
   cout<<"WPL="<<GetWPL(HTArray,code,leafNum)<<endl;
    return 0;
}
/**选择最小和次小结点*/
void selectMin(HTNode *HTArray,int k,int & minIndex1,int & minIndex2)
{
    // cout<<"本轮写第"<
    int min1,min2;//m2>=m1
    int i=0;//下标
    while(HTArray[i].parent!=-1&&i<k)//找出第一个未连接的结点 
    {
        i++;
    }
    minIndex1=i;
    min1=HTArray[minIndex1].weight;
    i++;
    while(HTArray[i].parent!=-1&&i<k)//找出第二个未连接的结点 
    {
        i++;
    }
    if(HTArray[i].weight<min1)//确保min2>min1 
    {
        min2=min1;
        minIndex2=minIndex1;
        min1=HTArray[i].weight;
        minIndex1=i;
    }
    else
    {
        minIndex2=i;
        min2=HTArray[i].weight;
    }
    i++;
    while(i<k)
    {
        if(HTArray[i].parent==-1)//无父母意味着未加入Huffman树
        {
            int w=HTArray[i].weight;
            if(w<min1)//比最小的还小
            {
                min2=min1;
                minIndex2=minIndex1;
                min1=w;
                minIndex1=i;
            }
            else if(w<min2)//介于两者之间
            {
                min2=w;
                minIndex2=i;
            }
            else//比最大的还大
            {

            }
        }
        i++;
    }
   //  cout<<" ******** "<
     return; 
   
}
/**创建哈夫曼树*/
void createHuffmanTree(HTNode * HTArray,int * weightArray,int leafNum)
{

     for(int i=0;i<leafNum;i++)
    {
        HTArray[i].left=-1;
        HTArray[i].right=-1;
        HTArray[i].parent=-1;
        HTArray[i].weight=weightArray[i];
    }

    for(int j=leafNum;j<2*leafNum-1;j++)
    {
        HTArray[j].left=-1;
        HTArray[j].right=-1;
        HTArray[j].parent=-1;
        HTArray[j].weight=0;
    }
   for(int i=leafNum; i<2*leafNum-1; i++)
    {
        int minIndex1=-1;
        int minIndex2=-1;
        selectMin(HTArray,i,minIndex1,minIndex2);
        HTArray[minIndex1].parent=i;
        //  cout<
        HTArray[minIndex2].parent=i;
        HTArray[i].left=minIndex1;
        HTArray[i].right=minIndex2;
        HTArray[i].weight=HTArray[minIndex1].weight+HTArray[minIndex2].weight;

    }
    
    return;
}
/**打印哈夫曼树*/
void printHufTree(HTNode *treeArray,int leafNum)
{
	cout<<"哈夫曼树:"<<endl; 
    for(int i=0; i<2*leafNum-1; i++)
    {
    	cout<<setw(2)<<i<<" "; 
        cout<<setw(2)<<treeArray[i].weight<<" ";
        cout<<"parent:"<<setw(2)<<treeArray[i].parent<<" left:"
            <<setw(2)<<treeArray[i].left<<" right:"<<setw(2)<<treeArray[i].right<<endl;
    }
    return;
}
/**哈夫曼编码*/
void huffmanCoding(HTNode * HTArray,char * code[],int leafNum)
{
   // cout<<" *****"<
    char *temp=new char[leafNum];
    temp[leafNum-1]='\0';
    for(int i=0; i<leafNum; i++)
    {
        int start=leafNum-1;
        int pos=i;
        int parent=HTArray[i].parent;
       // cout<
        while(parent!=UNCONSTRUCTED)
        {
            if(HTArray[parent].left==pos)
                temp[--start]='0';
            else if(HTArray[parent].right==pos)
                temp[--start]='1';
            pos=parent;
            parent=HTArray[pos].parent;
        }
        code[i]=new char[leafNum-start];

        strcpy(code[i],&temp[start]);

    }
    delete temp;
    return;
}


/**打印哈夫曼编码*/
void printCode(char * code[],char * data,int leafNum)
{
	cout<<"哈夫曼编码:"<<endl;
    for(int i=0; i<leafNum; i++)
    {
        cout<<data[i]<<" 's Huffmancode is: "<<code[i]<<endl;
    }
    return;
}
/**求WPL*/
int GetWPL(HTNode * HTArray,char * code[],int leafNum)
{
	int wpl=0;
	for(int i=0;i<leafNum;i++)
    {
        int lenght=strlen(code[i]);
        wpl+=HTArray[i].weight*lenght;
    }
    return wpl;
}

你可能感兴趣的:(Huffman Code)