Huffman编码输出算法

刚学完数据结构Huffman树,以此练一下手~(顺便写下第一篇日志)
基础不好啊~写得很快,就是查错查了半天……
最后总算运行正确了~
HuffmanCoding函数基本都写的差不多,Select函数是自己写的,写的当然不够飘逸啦,但是至少思路是对的吧~
我在代码后面都写了详细的注释~
以下是代码:
 
#include <iostream>
#include <string>
#define MAXSIZE 100
using namespace std;
 
typedef struct {
 unsigned int weight;
 unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char ** HuffmanCode;
 
void Select (HuffmanTree HT,int j,int &s1,int &s2) { //Select函数
 int i = 1;
 int unsigned tmp1,tmp2;
 tmp1 = unsigned int (-1);    //令tmp1和tmp2为最大的unsigned的数
 tmp2 = unsigned int (-1);
    int num1=0,num2=0;
    for (i=1;i<=j;++i) {
  if (HT[i].parent==0) {   //当某个元素的parent!=0时说明此元素已经被用过了,所以不能再作算
     if (HT[i].weight < tmp1) { //先选一个weigth最小的元素
         tmp1 = HT[i].weight;
         num1 = i;      //用num1记录编号
        }
  }
    }
 for (i=1;i<=j;++i) {
  if (HT[i].parent==0) {  //同上
   if (HT[i].weight <= tmp2 && HT[i].weight >= tmp1 && i!=num1) {
    //选一个比tmp1大的数中的最小权值元素赋值给tmp2.
    //i!=num1表示取过的元素项不能再取
    if (HT[i].weight!=tmp2) {
     //这里条件表示如果权值为tmp2的好几个,就取第一个为tmp2的编号
        tmp2 = HT[i].weight;
        num2 = i;
    }
   }
  }
 }
   
 if (num1<num2) {  //保证s1<s2
  s1 = num1;
  s2 = num2;
 }
 else {
  s1 = num2;
  s2 = num1;
 }
}

void HuffmanCoding (HuffmanTree &HT,HuffmanCode &HC,int *w,int n,char *elem) {  
 //*w处传入数组,代表各个元素的权数
 //*elem处传入元素(可以在main函数中实现,在这里是为了在函数体内实现才
 //多加的参数)
 if (n<=1) return;
 
 int m=2*n-1;
 int i;
 HuffmanTree p;
 
 p = (HuffmanTree)malloc(sizeof(HTNode));
 HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));
 
 //初始化表格
 for (p=HT+1,i=1;i<=n;++i,++p,++w) {
  p->weight = *w;
  p->parent = 0;
  p->lchild = 0;
  p->rchild = 0;
 }
 for (;i<=m;++i,++p) {
  p->parent = 0;
  p->rchild = 0;
  p->lchild = 0;
  p->weight = 0;
 }
   
 //往表格中填入元素
 for (i=n+1;i<=m;++i) {
  int s1,s2;
  Select (HT,i-1,s1,s2);  //从表中选出最小的2个数,并且不改变次序
  HT[s1].parent = i;
  HT[s2].parent = i;
  HT[i].lchild = s1;
  HT[i].rchild = s2;
  HT[i].weight = HT[s1].weight + HT[s2].weight;
 }
 //从叶子到根为字符编码
 HC = (HuffmanCode)malloc((n+1)*sizeof(char*));
 int start,c,f;
 char *cd;
 cd = (char *)malloc(n*sizeof(char));
 cd[n-1] = '/0';
 
 for (i=1;i<=n;++i) {
  start = n-1;
  for (c=i,f=HT[i].parent;f!=0;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));
  strcpy (HC[i],&cd[start]);  //把代码反置(因为从叶子到根,代码是反得)
  cout << "num:"<< i << " elem:" << elem[i] <<  //输出
   " weight:" << HT[i].weight << " code:" << HC[i] << endl;
 }
 free (cd);  //释放空间
}
int main() {
 HuffmanTree HT;
 HuffmanCode HC;
 int n,i;
 cout << "Please input how many elements you have:";
 cin >> n;
 char elem[MAXSIZE];  //存储元素
 int priority[MAXSIZE]; //存储权值
 for (i=1;i<=n;i++) { //输入
  cout << "Please input your the " << i <<
   "th element and its priority:";
  cin >> elem[i];
  cin >> priority[i-1];
 }
 cout << endl;
 HuffmanCoding (HT,HC,priority,n,elem);
 
 system ("pause");
 
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值