33,317
社区成员
发帖
与我相关
我的任务
分享
void SelectMin(HNode*a,int n,int b[])//从结点数组中选出最小的两个
{
int i, min1,min2;
/*
****************************修改****************************
*确实又欠考虑了,遍历的时候应该剔除下标为b[0] 和 b[1]
* b[0] 和 b[1] 不一定为 0 和 1
************************************************************
*/
for (i = 0; a[i].parent != -1 && i < n; i++);
min1 = a[i].weight;
b[0] = i;
for (++i; a[i].parent != -1 && i < n; i++);
min2 = a[i].weight;
b[1] = i;
if (min1 > min2)
{
int tmp = b[0];
b[0] = b[1];
b[1] = tmp;
tmp = min2;
min2 = min1;
min1 = tmp;
}
for(int i=0;i<n;i++)
{
if (i == b[0] || i == b[1])
continue;
if ( a[i].weight<=min1 && a[i].parent==-1 )
{
min2=min1;
min1=a[i].weight;
b[1]=b[0];
b[0]=i;
}
else if ( a[i].weight<=min2 && a[i].parent==-1)
{
min2=a[i].weight;
b[1]=i;
}
}
}
#include<iostream>
#include<string.h>
#include <stdlib.h>
using namespace std;
struct HNode
{
int weight;
int lchild, rchild, parent;
};
//huffman编码表C++描述:
struct HCode
{
char data;
char code[100];
}; //字符及其编码结构
class Huffman
{
private:
HNode* huffTree; //Huffman树
HCode* HCodeTable; //Huffman编码表
public:
void CreateHTree(int a[], int n); //创建huffman树
void CreateCodeTable(char b[], int n); //创建编码表
void Encode(char *s, char *d); //编码
void Decode(char *s, char *d,int n); //解码
~ Huffman();
};
void SelectMin(HNode*a,int n,int b[])//从结点数组中选出最小的两个
{
int i, min1,min2;
/*
****************************修改****************************
*尽量保持了楼主的数据结构定义和思路
*
*在SelectMin中首先min1 和 min2的初始化原来有些瑕疵
*
*min1 和 min2初始化时应该淘汰parent不为-1的节点。如果只
*加入一开始选择a[0]作为min1,而且a[0]又恰好是所有节点中权重
*最小的节点,那么该函数永远会返回0下标。
*
************************************************************
*/
for (i = 0; a[i].parent != -1 && i < n; i++);
min1 = a[i].weight;
b[0] = i;
for (++i; a[i].parent != -1 && i < n; i++);
min2 = a[i].weight;
b[1] = i;
if (min1 > min2)
{
int tmp = b[0];
b[0] = b[1];
b[1] = tmp;
}
for(int i=2;i<n;i++)
{
if ( a[i].weight<=min1 && a[i].parent==-1 )
{
min2=min1;
min1=a[i].weight;
b[1]=b[0];
b[0]=i;
}
else if ( a[i].weight<=min2 && a[i].parent==-1)
{
min2=a[i].weight;
b[1]=i;
}
}
}
void Huffman::CreateHTree(int a[], int n)//初始化Huffman树
{
//根据权重数组a[1->n] 初始化Huffman树
huffTree = new HNode [2*n-1];
for (int i = 0; i < n; i++)
{
huffTree[i].weight = a[i];
huffTree[i].lchild = -1;
huffTree[i].rchild = -1;
huffTree[i].parent = -1;
cout<<huffTree[i].weight<<" "<<huffTree[i].lchild<<" "<<huffTree[i].rchild<<" "<<huffTree[i].parent<<endl;
}
int re[2];
int li, ri;
cout<<endl;
for (int i = n; i < 2*n-1; i++) //开始建Huffman树
{
//从0~i-1中选出两个权值最小的结点,选过的不再选入
SelectMin(huffTree, i, re);
li=re[0],ri=re[1];
huffTree[li].parent = huffTree[ri].parent = i;
huffTree[i].weight = huffTree[li].weight+huffTree[ri].weight;
huffTree[i].lchild = li;
huffTree[i].rchild = ri;
huffTree[i].parent = -1;
}
for(int i=0;i< 2*n-1;i++)
cout<<huffTree[i].weight<<" "<<huffTree[i].lchild<<" "<<huffTree[i].rchild<<" "<<huffTree[i].parent<<endl;
}
void Reverse(char*p)
{
int n=strlen(p);
char *change = new char[n];
for(int j=0;j<n;j++)
{
change[j]=p[j];
}
for(int f=0;f<n;f++)
{
p[f]=change[n-1-f];
}
}
void Huffman::CreateCodeTable(char b[],int n)//生成编码表
{
HCodeTable=new HCode[n];
for(int i=0;i<n;i++)
{
HCodeTable[i].data=b[i];
int child=i;
int parent=huffTree[i].parent;
int k=0;
while(parent!=-1)
{
if (child==huffTree[parent].lchild)
HCodeTable[i].code[k]='0';
else
HCodeTable[i].code[k]='1';
k++;
child=parent;
parent=huffTree[child].parent;
}
HCodeTable[i].code[k]='\0';
Reverse(HCodeTable[i].code);
cout<<HCodeTable[i].data<<" "<<HCodeTable[i].code<<endl;
}
}
void Huffman::Decode(char*s,char*d,int n)//解码,s为编码串,d为解码后的字符串
{
while(*s!='\0')
{
int parent=2*n-1-1;
while(huffTree[parent].lchild!=-1)
{
if(*s=='0')
parent=huffTree[parent].lchild;
else
parent=huffTree[parent].rchild;
s++;
}
*d=HCodeTable[parent].data;
d++;
}
}
Huffman::~Huffman()
{
int m,n;
m=sizeof(huffTree)/sizeof(huffTree[0]);
for(int i=0;i<m;i++)
delete huffTree++;
n=sizeof(HCodeTable)/sizeof(HCodeTable[0]);
for(int j=0;j<n;j++)
delete HCodeTable++;
}
int main()
{
int binary[5]={21,2,5,63};
char zifu[5]={'a','b','c','d'};
Huffman hafuman;
hafuman.CreateHTree(binary,4);
hafuman.CreateCodeTable(zifu, 4);
system("pause");
}