哈夫曼树的创建及编码

匿名 (未验证) 提交于 2019-12-02 22:56:40

哈夫曼树编码:从根节点开始,按左子树为'0',右子树为'1'编码,最后找到叶子节点的编码

 #include <stdio.h>    #include <malloc.h>   #include <conio.h>    #include <string.h>   #include <iostream>   using namespace std;      #define MAX_LENGTH 100//叶子节点的最大数量    typedef char **HuffmanCode;      typedef struct HTNode{       unsigned int weight;//该节点所占的权重        unsigned int parent,lchild,rchild;// 该节点的父节点,左孩子,右孩子        HTNode(unsigned int a,unsigned int b,unsigned int c,unsigned int d){           weight=a,parent=b,lchild=c,rchild=d;       }   }HTNode,*HuffmanTree;      void Select(HuffmanTree HT,int i,int &s1,int &s2){//把没有父节点的所有节点中最小的两个值赋值给s1,s2        int j,k = 1;       while(HT[k].parent) //找最小的父节点为0,即没有父节点的点            k++;       s1 = k;       for(j = 1;j <= i;j++)           if(!HT[j].parent && HT[j].weight<HT[s1].weight)//找父节点为0的所有节点中的最小值,赋给s1                  s1 = j;       k = 1;       while(HT[k].parent || k==s1)//找最小的父节点为0,即没有父节点的点,且不等于s1            k++;       s2 = k;       for(j = 1;j <= i;j++)           if(!HT[j].parent && HT[j].weight<HT[s2].weight && j!=s1)//找父节点为0的所有节点中的不为s1的最小值,赋给s2                s2 = j;   }      void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){//创建哈夫曼树        if(n<=1) return;//只有一个节点,直接作为根节点返回,其他情况直接返回        int m,i,s1,s2,start,c,f;       HuffmanTree p;       m = 2*n-1;//哈夫曼树的总节点数量        for(p = HT+1,i=1;i<=n;i++,p++,w++){//给前n个节点赋值            *p=HTNode(*w,0,0,0);           cout<<endl<<"HT["<<i<<"].weight="<<p->weight<<"  ";//输出每个节点的权值        }       for(;i<=m;i++,p++)           *p=HTNode(0,0,0,0);//给后面m-n个节点赋值        cout<<endl<<endl<<"HuffmanTree is created in following order :";       for(i = n+1;i<=m;i++){           Select(HT,i-1,s1,s2);//每次选择节点中最小的两个节点作为新树的左子树,右子树;           // 把s1,s2作为节点i的左子树,右子树,           HT[s1].parent = i,HT[s2].parent = i;//给s1,s2的父节点赋值             HT[i].weight=HT[s1].weight+HT[s2].weight;//计算节点i的权重            cout<<endl<<"HT["<<s1<<"] and HT[" <<s2<<"] create";           cout<<" HT["<<i<<"], weight="<<HT[i].weight;       }       //从叶子结点到根结点逆向求每个字符的哈夫曼编码       HC = (HuffmanCode)malloc((n+1)*sizeof(char *));//为数组HC开辟空间       char cd[MAX_LENGTH];         cd[n-1]=0;//编码结束符'\0'的ascii码为0        cout<<endl<<endl<<"HuffmanTree Code is as follows :"<<endl;       for(i=1;i<=n;i++){//逐个字符求哈夫曼编码           start = n-1;//指向编码结束的位置            //每个节点的左子树编码为'0',右子树编码为'1', 按从根节点往下的顺序构造出叶子节点的编码            for(c=i,f=HT[i].parent;f;c=f,f=HT[f].parent)//从叶子节点一直找到根节点                if(HT[f].lchild==c) cd[--start]='0';//若为左子树,编码位置编为'0'                else cd[--start]='1';//若为右子树,编码位置编为'1'            HC[i]=(char *)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间,n-start为第i个字符的编码长。            strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC            printf("\nHT[%d] node 's  Huffman code is: %s",i,HC[i]);       }          }      int main()   {       HuffmanTree HT;       HuffmanCode HC;       int n,i;       int *w,W[MAX_LENGTH];//W保存叶子节点的权值        cout<<endl<<endl<<"HuffmanCoding.cpp";       cout<<endl<<"============="<<endl;       cout<<endl<<"Please input the number of the element of HuffmanTree (eg.5):";       cin>>n;//输入叶子节点的数量        for(i = 0;i < n;i++){           cout<<"Please input the weight of the "<<i+1<<"th element (eg.8):";           cin>>W[i];//输入每个叶子节点的权值        }       w = W;       HuffmanCoding(HT,HC,w,n);//创建n个叶子节点构成的哈夫曼树        cout<<endl<<endl<<"...OK!...";//创建成功        getch();       return 0;   } 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!