数据结构_树_赫夫曼树及赫夫曼编码_C++实现

传说中的最优二叉树——赫夫曼(Huffman)树

本例采用如下存储结构:


实例:
数据结构_树_赫夫曼树及赫夫曼编码_C++实现_第1张图片
下面这个是严蔚敏《数据结构》C语言版上的赫夫曼编码存储结构
我换了一种方式,开了一个栈然后反复用,具体见代码:
数据结构_树_赫夫曼树及赫夫曼编码_C++实现_第2张图片
"head.h"


#include<iostream>
#include<stack>
using namespace std;

class NODE
{
public:
	NODE();
	int weight,parent,lchild,rchild;
};

NODE::NODE()
{
	weight=parent=lchild=rchild=0;
}

class HUFFMAN
{
public:
	HUFFMAN();
	void GetHuffmanCode();//获得赫夫曼编码主调函数
private:
	void GetHuffmanNode();//获得节点
	void HuffmanCoding();//编码
	void PrintHuffmanCode();//输出编码
	void Select(int &,int &);//从森林中选择两颗权值较小的树
	int len,cur;//len表示表长度cur表示当前指示的节点
	NODE * HT;//HT指向表头结点
};

HUFFMAN::HUFFMAN()
{
	len=cur=0;
	HT=NULL;
}

void HUFFMAN::GetHuffmanCode()//获得赫夫曼编码主调函数
{
	GetHuffmanNode();
	HuffmanCoding();
	PrintHuffmanCode();
}

void HUFFMAN::GetHuffmanNode()//获得节点
{
	cout<<"GetHuffmanNode Called !"<<endl<<endl;
	cout<<"Please Enter The Weight Of Each Node ."<<endl<<endl;
	NODE node[100];
	int i=0,t;
	while(cin>>t)
	{
		node[i++].weight=t;
	}
	cin.clear();
	len=i;
	HT=new NODE[2*i];
	for(i=1;i<=len;i++)
		*(HT+i)=node[i-1];
	cur=len+1;
}

void HUFFMAN::HuffmanCoding()//编码
{
	cout<<"HuffmanCoding Called !"<<endl<<endl;
	while(cur<2*len)//建树过程
	{
		int a,b;
		Select(a,b);//选择两颗权值较小的子树
		(HT+cur)->weight=(HT+a)->weight+(HT+b)->weight;//连接成新树并更该其权值
		(HT+cur)->lchild=a;
		(HT+cur)->rchild=b;
		cur++;
	}
}

void HUFFMAN::PrintHuffmanCode()//输出编码
{
	cout<<"PrintHuffmanCode Called !"<<endl<<endl;
	cout<<"The Huffman Code Is :"<<endl<<endl;
	stack<int> s;//定义一个栈存放编码
	for(int i=1;i<=len;i++)//从叶子节点向上查找到根节点
	{
		cout<<(HT+i)->weight<<" : ";
		int j=i;
		do
		{
			if((HT+(HT+j)->parent)->lchild==j)//左子树表示为0
				s.push(0);
			else//右子树表示为1
				s.push(1);
			j=(HT+j)->parent;//j指向其父节点
		}while((HT+j)->parent!=0);//未查找到根节点时进行查找
		while(!s.empty())//输出编码
		{
			cout<<s.top()<<" ";
			s.pop();
		}
		cout<<endl;
	}
}

void HUFFMAN::Select(int &a,int &b)//从森林中选择两颗权值较小的树
{
	int min;
	bool first=true;
	for(int i=1;i<cur;i++)//从表中获得min的值并得到a其中有个小技巧不知道您看懂了木有?
	{
		if((HT+i)->parent==0&&(first==true||(HT+i)->weight<min))
		{
			a=i;
			min=(HT+i)->weight;
			if(first==true)
				first=false;
		}
	}
	first=true;
	(HT+a)->parent=cur;//更改a的父节点
	for(int i=1;i<cur;i++)//从表中获得min的值并得到b
	{
		if((HT+i)->parent==0&&(first==true||(HT+i)->weight<min))
		{
			b=i;
			min=(HT+i)->weight;
			if(first==true)
				first=false;
		}
	}
	(HT+b)->parent=cur;//更改b的父节点
	if(a>b)//如有必要调整a、b次序
	{
		int t=a;
		a=b;
		b=t;
	}
}




"main.cpp"



#include<iostream>
#include"head.h"
using namespace std;

int main()
{
	HUFFMAN ht;
	ht.GetHuffmanCode();
	system("pause");
}


你可能感兴趣的:(数据结构_树_赫夫曼树及赫夫曼编码_C++实现)