#include<iostream>
#include<iomanip>
#include<stack>
using namespace std;
struct element
{
int weight;
int lchild, rchild, parent;
};
class HTree
{
element *node;
int n, m;
stack<int> code;
int setcode(int weight);
public:
HTree(int _n, int _weight[]);
~HTree();
void select(int &s1,int &s2);
void createHT();
int search(int weight);
void print();
void printHTcode();
};
HTree::HTree(int _n, int _weight[])
{
n = _n;
m = 2 * n - 1;//n个元素需要2n-1个空间
node = new element[m];
for (int i = 0; i < n; i++)
{
node[i].weight = _weight[i];
}
for (int i = 0; i < m; i++)
{
node[i].lchild = node[i].rchild = node[i].parent = 0;//初始化为0
}
createHT();
}
HTree::~HTree()
{
delete node;
}
void HTree::select(int &s1, int &s2)
{
for (int i = 0; i < n; i++)
{
if (node[i].parent == 0)
{
s1 = i;//临时元素
break;
}
}
for (int i = 0; i < n; i++)
{
if ((node[i].weight < node[s1].weight) && (node[i].parent == 0))
{
s1 = i;
}
}
for (int i = 0; i < n; i++)
{
if ((node[i].parent == 0)&&(i!=s1))
{
s2 = i;
break;
}
}
for (int i = 0; i < n; i++)
{
if ((node[i].weight < node[s1].weight) && (node[i].parent == 0) && (i != s1))
s2 = i;
}
}
void HTree::createHT()
{
for (int i = n; i < m; i++)
{
int s1, s2;//左小右大
select(s1,s2);
node[s1].parent = i;
node[s2].parent = i;
node[i].lchild = s1;
node[i].rchild = s2;
node[i].weight = node[s1].weight + node[s2].weight;
n++;
}
}
int HTree::setcode(int weight)
{
int location, parent, k;//k为移动指针
int count = 0;
location = search(weight);
k = location;
parent = node[location].parent;
while ((node[k].parent != 0) && (k != -1))
{
if (node[parent].lchild == k)
{
code.push(0);
}
else
{
code.push(1);
}
k = node[k].parent;
parent = node[k].parent;
count++;
}
if (k == -1)
cout << "未找到!" <<endl;
return count;
}
int HTree::search(int weight)
{
int result = -1;
for (int i = 0; i < m; i++)
{
if (node[i].weight == weight)
{
result = i;
}
}
return result;
}
void HTree::print()
{
cout << "索引 权值 双亲 左孩子 右孩子" << endl;
cout << left;//左对齐
for (int i = 0; i < m; i++)
{
cout << setw(5) << i << " ";
cout << setw(6) << node[i].weight << " ";
cout << setw(6) << node[i].parent << " ";
cout << setw(6) << node[i].lchild << " ";
cout << setw(6) << node[i].rchild << endl;
}
cout << "哈夫曼树打印完毕"<<endl;
}
void HTree::printHTcode()
{
cout << "请输入要查询的编码的权值" << endl;
int weight, size;
cin >> weight;
size = setcode(weight);
cout << "权值" <<weight<< "编码长度" <<size<< endl;
cout << "编码结果为";
for (int i = 0; i < size; i++)
{
cout << code.top()<<" ";
code.pop();
}
cout << endl;
}
int main()
{
cout << "请输入要构造的哈夫曼树的结点个数" <<endl;
int n, *weight;
cin >> n;
weight = new int[n+1];
cout << "请输入这" << n << "个元素的权值" << endl;
for (int i = 0; i < n; i++)
{
cin >> weight[i];
}
HTree test(n, weight);
test.print();
test.printHTcode();
system("pause");
return 0;
/*修改*/
}
测试结果: