贪心算法-Huffman算法3

源代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
struct HtNode{
double weight;
int parent,lchild,rchild;
};
struct HtTree{
HtNode* ht;
int root;
};
typedef struct HtTree* PHtTree;
//构造有n个节点的哈夫曼树
PHtTree Huffman (int n,int* w)
{
PHtTree pht;
HtNode* ht;
//用于记录权值最小的两棵树在数组中的位置
int i,j,p1,p2;
//min1,min2用于记录两个最小的权值
double min1,min2;
//输入合法
if(n<=0) return 0;
//动态分配Haffman树的空间
//int*n=(int*)malloc(sizeof(int)*n);
pht=(HtTree*)malloc(sizeof(HtTree));
pht->ht=(HtNode*)malloc(sizeof(HtNode)*(2*n-1));
//n个叶子共有2*n-1个节点
//初始化,设置ht数组的初始值
for(i=0;i<2*n-1;i++)
{
pht->ht[i].parent=0;
if(i<n)
{
pht->ht[i].weight=w[i];
}
else
{
pht->ht[i].weight=1000;
}
}
//执行n-1次合并操作,即构造哈夫曼树的n-1个内部节点
for(i=0;i<n-1;i++)
{
p1=p2=0;
//相关变量赋初值
min1=min2=1000;//相当于一个大数
for(j=0;j<n+i;j++)
{
if(pht->ht[j].parent==0)
{
if(pht->ht[j].weight<min1)
{
min1=pht->ht[j].weight;
p1=j;
}
}
}
for(j=0;j<n+i;j++)
{
if(pht->ht[j].parent==0)
{
if((pht->ht[j].weight>min1)&&(pht->ht[j].weight<=min2)&&(j!=p1))
{
min2=pht->ht[j].weight;
p2=j;
}
}
}
pht->ht[p1].parent=n+i;
pht->ht[p2].parent=n+i;
pht->ht[n+i].weight=min1+min2;
pht->ht[n+i].lchild=p1;
pht->ht[n+i].rchild=p2;
}
//返回树
return pht;
}
//计算Huffman编码
void HuffmanCode(char** HC,int n,PHtTree pht)
{
int flag;
//每个字符的编码最大长度不会超过n
//这跟树的深度有关
char*c;
//c=(char*)malloc(sizeof(char)*n);
//分配n个字符指针数组空间
//第n-1单元存储编码串的结束符
int start;
//逐个对n个字符求其哈夫曼编码
for(int i=0;i<n;i++)
{
flag=0;
//start=n-1;
//k,f是两个工作指针,f指向k的父亲
for(int k=i,f=pht->ht[i].parent;f!=0;k=f,f=pht->ht[k].parent)
{
flag++;
//左边分配0,右边分配1
}
//---------------
c=(char*)malloc(sizeof(char)*(flag));
c[flag]='\0';
for(int k=i,f=pht->ht[i].parent;f!=0;k=f,f=pht->ht[k].parent)
{
if(pht->ht[f].lchild==k)
{
c[--flag]='0';
}
else
{
c[--flag]='1';
}
}
//为第i个字符编码分配空间
//因为路径有长有短
HC[i]=(char*)malloc(sizeof(char));
strcpy(HC[i],c);
}
}
int main()
{
//输入
int n;
int m;
HtNode* ht;
int* weight;
char** HC;
PHtTree pht;
printf("请输入需要哈夫曼编码的节点数目\n");
scanf("%d",&n);
//分配内存空间
ht=(HtNode*)malloc(sizeof(HtNode)*n);
weight=(int*)malloc(sizeof(int)*n);
HC=(char**) malloc(sizeof(char*)*n);
printf("请输入各节点的值\n");
for(int i=0;i<n;i++)
{
printf("第%d个节点的权值:\n",i);
scanf("%d",&m);
weight[i]=m;
printf("\n");
}
//构造具有n个节点的Haffman树
pht=Huffman(n,weight);
HuffmanCode(HC,n,pht);
//输出编码
for(int i=0;i<n;i++)
{
int j=0;
printf("第%d个字符的编码,它的权值为是%d:\n",i,weight[i]);
{
printf("%s\n",HC[i]);
//j++;
}
}
return 0;
}

 

posted @ 2012-10-01 14:16  zhouqian7890  阅读(233)  评论(0编辑  收藏  举报