哈夫曼树的构造与哈夫曼编码的生成过程。
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<string.h>
#define MAXSIZE 1000
using namespace std;
typedef struct{
int weight; //权值
int parent,lchild,rchild; //父母节点,左子树,右子书
}HTNode,*HuffmanTree;
typedef char **HuffmanCode; //动态分配数组存储Huffman编码表
void Select(HuffmanTree &HT,int i,int &s1,int &s2){
int MIN1=100000001;
int MIN2=100000000;
for(int j = 1; j <= i; j++){
if(HT[j].parent==0){
if(HT[j].weight<MIN1){
MIN1=HT[j].weight;
s1=j;
}
}
}
for(int j = 1; j <= i; j++){
if(HT[j].parent==0&&j!=s1)
{
if(HT[j].weight<MIN2){
MIN2=HT[j].weight;
s2=j;
}
}
}
}
void CreateHuffmanTree(HuffmanTree &HT,int n,int num[]){ //构造哈夫曼树
int M=2*n-1;
if(n<=1) return;
for(int i;i<=M;i++){//初始化HuffmanTree
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
HT[i].weight=0;
}
cout<<"请输入权值:"<<endl;
for(int i=1;i<=n;i++){
scanf("%d",&HT[i].weight); //输入HuffmanTree权值
}
for(int i=1;i<=M;i++){
num[i]=i;
}
//创建HuffmanTree
int s1;
int s2;
for(int i = n+1; i <= M; i++){
Select(HT, i-1, s1, s2); //在HT[k]中选择一个双亲域为0,且权值最小的结点,返回序号s1,s2
HT[s1].parent=i;
HT[s2].parent=i; //得到新结点i,从森林中删除s1,s2,将s1,s2的双亲域改为i
HT[i].lchild=s1;
HT[i].rchild=s2; //s1,s2成为HT[i]的左右子树
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
}
//打印HuffmanTree
void PrintHuffmanTree(HuffmanTree HT,int *num,int n){
int M=2*n-1;
printf("\n");
cout<<"Date weight paraent lchild rchild\n";
for(int i=1;i<=M;i++){
printf(" %d %6d %6d %7d %7d\n", num[i], HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
}
printf("\n");
}
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n){
char cd[n];
HC = new char*[n+1];
// cd = new char[n];
cd[n-1]='\0';
int start;
int c,f;
for(int i=1;i <=n; i++){
start = n-1;
c=i; f=HT[i].parent;
while(f!=0){
--start;
if(HT[f].lchild==c) cd[start] = '0';
else cd[start] = '1';
c=f; f=HT[f].parent;
}
HC[i]= new char[n-start];
strcpy(HC[i],&cd[start]);
}
// delete cd;
}
void printHuffmanCoding(HuffmanCode HC, int num[],int n){
printf("\n");
for(int i = 1; i <= n; i++){
printf("%d:%s\n", num[i], HC[i]);
}
printf("\n");
}
//void DecodeHuffmanCoding(HuffmanTree HT,char *ch,char Huff[],int len,char *Decode,int n){
// int a = 2*n-1; //最后一个为根节点,前n个为叶子节点
// int b = 0;
// int c = 0;
// while(b<len){
// if(Huff[b]=='0'){
// a=HT[a].rchild;
// }
// if(Huff[b]=='1'){
// a=HT[a].lchild;
// }
// if(a<=n){
// Decode[c]=ch[a];
// c++;
// a=2*n-1;
// }
// b++;
// }
// Decode[c]='\0';
//}
int main(){
HuffmanTree HT;
int n;
int M;
int num[MAXSIZE];
cout<<"请输入节点数:";
cin>>n;
M=2*n-1;
HT=new HTNode[M+1];
CreateHuffmanTree(HT,n,num);
PrintHuffmanTree(HT,num,n);
char cd[n+1];
HuffmanCode HC;
CreatHuffmanCode(HT,HC,n);
printHuffmanCoding(HC,num,n);
// cout<<"请输入Huffman编码:";
// char Huff[100];
// scanf("%s",&Huff);
// int len=strlen(Huff);
// char Decode[100];
// DecodeHuffmanCoding(HT,ch,Huff,len,Decode,n);
// printf("%s",Decode);
return 0;
}