// Haffman.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
typedef char DataType;

struct element  //结点定义
{     
  DataType data;
  float weight;//此字符的权值
      int parent,lchild, rchild;//父结点,左孩子,右孩子存放位置
};
#define MAXLEAF 6 //最大叶子结点数目,待编码的字符数
#define MAXNODE MAXLEAF*2-1   //最大结点数
struct Huffmancode{
   DataType ch;//存放字符
   char bits[MAXLEAF];//存放字符的哈夫曼编码
};
Huffmancode hcode[MAXLEAF];
//element ht[ MAXNODE];

//此函数为选取两个最小的权值结点的位置 分别分别存放在pn[0],pn[1]
void Select (element *pt,int n, int *pn){
    int i,iposi=0;
float tmp;
for(i=0;i<n;i++){
 if(pt[i].parent==-1)
         {
          tmp=pt[i].weight;pn[0]=i;
  iposi=i;
  break;
 }
}
for(i=iposi;i<n;i++){
if(tmp>pt[i].weight && pt[i].parent==-1){
            pn[0]=i; tmp=pt[i].weight;
}
}


    for(i=0;i<n;i++){
 if(pt[i].parent==-1 && i!=pn[0])
         {
          tmp=pt[i].weight;pn[1]=i;
  iposi=i;
  break;
 }
}
    for(i=iposi;i<n;i++){
if(tmp>pt[i].weight && pt[i].parent==-1 && i!=pn[0]){
            pn[1]=i; tmp=pt[i].weight;
}
}
   return;
}

//此函数功能为创建哈夫曼树
void CreateHuffmanTree(element *pt){
    int i,k=0;
int pn[2];
for(i=MAXLEAF ;i<MAXNODE;i++){
//选取两个最小的权值结点的位置 分别分别存放在pn[0],pn[1]
        Select(pt,MAXLEAF+k,pn);
        k++;
pt[pn[0]].parent=pt[pn[1]].parent=i;
pt[i].lchild=pn[0]; pt[i].rchild=pn[1];
pt[i].weight=pt[pn[0]].weight+pt[pn[1]].weight;
}
}

//此函数功能为生成哈夫曼编码
void CreateHuffmanCode(element *pt,int n){
   int i,p,j,start;
   char cd[MAXNODE];
   for(i=0;i<n;i++){
 start=n-1;
     cd[start]=0;
 p=pt[i].parent;
 j=i;

 //从叶子结点出发,逐层遍历到根结点,逆序求出每个结点的哈夫曼编码
 while(p!=-1){//当p为 -1时,表示遍历到根结点
        if(pt[p].lchild==j)
cd[--start]='0';//左孩子编码为0
else 
cd[--start]='1'; //右孩子编码为1
j=p;
p=pt[p].parent;
 }
 strcpy(hcode[i].bits,&cd[start]);
   }
}

int main(int argc, char* argv[])
{

 element ht[MAXNODE];
 int i;
 for(i=0;i<MAXNODE;i++) {
   ht[i].parent=-1;
   ht[i].lchild=-1;
   ht[i].rchild=-1;
   ht[i].data=' ';
   ht[i].weight=0;    
 }
/[0].data='A' ;ht[0].weight=2;  hcode[0].ch=ht[0].data;
/[1].data='B' ;ht[1].weight=4;  hcode[1].ch=ht[1].data;
/[2].data='C' ;ht[2].weight=5;  hcode[2].ch=ht[2].data;
/[3].data='D' ;ht[3].weight=3;  hcode[3].ch=ht[3].data;

ht[0].data='A' ;ht[0].weight=28;  hcode[0].ch=ht[0].data;
ht[1].data='B' ;ht[1].weight=13;  hcode[1].ch=ht[1].data;
ht[2].data='C' ;ht[2].weight=30;  hcode[2].ch=ht[2].data;
ht[3].data='D' ;ht[3].weight=10;  hcode[3].ch=ht[3].data;
ht[4].data='E' ;ht[4].weight=12;  hcode[4].ch=ht[4].data;
ht[5].data='F' ;ht[5].weight=7;  hcode[5].ch=ht[5].data;

 
 CreateHuffmanTree(ht);//生成哈夫曼树
CreateHuffmanCode(ht,MAXLEAF);//生成哈夫曼编码

//输出每个字符的编码
float weight=0;
for(i=0;i<MAXLEAF;i++){
   weight +=ht[i].weight*strlen(hcode[i].bits);
   printf("字符=%c 权值=%f 编码=%s\n",hcode[i].ch, ht[i].weight,hcode[i].bits);
}
printf("weight=%f\n",weight);
return 0;

一组字符{A, B, C, D, E, F,}出现的频率分别是{28, 13, 30, 10, 12, 7}