简单的哈夫曼树,代码如下,不知道哪里错了,运行结果不正确

lengyuenanfeng 2014-09-22 11:24:59
//哈夫曼树的C++描述
#include<iostream>
#include<string.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 min1,min2;
min1=a[0].weight<a[1].weight? a[0].weight:a[1].weight;
min2=a[0].weight>a[1].weight? a[0].weight:a[1].weight;
b[0]=0;
b[1]=1;
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[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);
}
...全文
177 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
lengyuenanfeng 2014-09-24
  • 打赏
  • 举报
回复
谢谢,搞定了!
gojoy_x13 2014-09-23
  • 打赏
  • 举报
回复

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;
		}
	}
}
lengyuenanfeng 2014-09-23
  • 打赏
  • 举报
回复
引用 1 楼 gojoy_x13 的回复:

#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");
} 
SelectMIn函数是错了,但这么改后若数组a[0]的权重最大就出错了,比如int binary[4]={211,2,5,63};
gojoy_x13 2014-09-23
  • 打赏
  • 举报
回复

#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");
} 

33,317

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧