给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
代码如下:(代码为老师所给)
#include<iostream>
using namespace std;
struct HTNode //哈夫曼树节点;
{
char ch;
int weight,parent,lchild,rchild;
};
class HuffmanTree //哈夫曼树树
{
public:
HuffmanTree(int n,char a[],int w[])
{
m_Htsize=0;
m_Ht=NULL;
_Create(n,a,w);
}
~HuffmanTree()
{
delete [] m_Ht;
}
void print();//打印哈夫曼树;
private:
int m_Htsize;
HTNode* m_Ht;
void _Create(int n,char a[],int w[]);//构建哈夫曼树树
int _MinVal(const int & i);
void _Select(int i,int &s1,int &s2);
};
void HuffmanTree::_Create(int n,char a[],int w[])
{
int s1=-1,s2=-1,i;
m_Ht=new HTNode[2*n-1];
m_Htsize=2*n-1;
for(i=0;i<n;i++)
{
m_Ht[i].ch=a[i];
m_Ht[i].weight=w[i];
m_Ht[i].lchild=-1;
m_Ht[i].rchild=-1;
m_Ht[i].parent=-1;
}
for(;i<2*n-1;i++)
{
_Select(i,s1,s2);
m_Ht[s1].parent=i;
m_Ht[s2].parent=i;
m_Ht[i].weight=m_Ht[s1].weight+m_Ht[s2].weight;
m_Ht[i].lchild=s1;
m_Ht[i].rchild=s2;
m_Ht[i].parent=-1;
}
}
//找到第i个节点前权重最小的节点
int HuffmanTree::_MinVal(const int & i)
{
int x=10000,k=0;
for(int j=0;j<i;j++)
{
if(m_Ht[j].parent==-1&&m_Ht[j].weight<x)
if(m_Ht[j].weight<x)
{
x=m_Ht[j].weight;
k=j;
}
}
m_Ht[k].parent=10000;
return k;
}
//找到第i个节点前权重最小的两个
void HuffmanTree::_Select(int i,int &s1,int &s2)
{
s1=_MinVal(i);
s2=_MinVal(i);
}
void HuffmanTree::print()
{
int i;
cout << "所建哈夫曼树的静态链表表示如下:" << endl;
cout << "位置 " << "字符 " << "权值 "
<< "双亲 " << "左孩子 " << "右孩子" << endl;
for(i = 0;i<(m_Htsize+1)/2; i++){
cout << " " << i << " " << m_Ht[i].ch
<< " " << m_Ht[i].weight << " ";
cout << m_Ht[i].parent << " "
<< m_Ht[i].lchild << " " << m_Ht[i].rchild << endl;
}
for (; i < m_Htsize; i++){
cout << " " << i << " " << m_Ht[i].weight
<< " " << m_Ht[i].parent << " ";
cout << m_Ht[i].lchild << " " << m_Ht[i].rchild << endl;
}
cout << endl;
}
int main()
{
int n;
cout << "请输入树叶结点的个数(小于等于1结束):" << endl;
cin>>n;
char chA[256];
int weightA[256];
for(int i= 0 ; i < n; i++){
cout << "请输入第" << i << "个字符及权值" << endl;
cin >> chA[i] >> weightA[i];
}
HuffmanTree ht(n,chA,weightA);
ht.print();
return 0;
}