Files
Data_Structure/Chapter5/Huffmn/HumanTree.cpp

165 lines
3.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include"iostream"
#include<iomanip>
#include<string>
using namespace std;
struct HTNode
{
int weight; // 权值,设为整型
int parent; // 双亲位置
int lchild; // 左孩子位置
int rchild; // 右孩子位置
};
void select(HTNode* HT, int k, int& i1, int& i2) // 在前K-1个结点中选择权值最小的两个根结点i和j
{
int m1, m2;
m1 = m2 = 32767; //
i1 = i2 = 0;
for (int j = 0; j < k; j++)
{
if (HT[j].weight < m1 && HT[j].parent == -1)
{
m2 = m1, i2 = i1;
m1 = HT[j].weight;
i1 = j;
}
else if (HT[j].weight < m2 && HT[j].parent == -1)
{
m2 = HT[j].weight;
i2 = j;
}
}
}
// 算法5.16 // 构造哈夫曼树
void HuffmanTree(HTNode*& HT, int* w, int n)
{ // n是叶子结点的个数w是叶子结点的权值数组
HTNode* p;
int k, i;
int i1, i2;
p = HT;
for (i = 0; i < 2 * n - 1; i++)
{ // 设置初始状态,所有结点的指针为空
HT[i].weight = 0;
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
}
for (i = 0; i < n; i++)
{ // 前n个结点的权值分别为个结点的权值
HT[i].weight = w[i];
}
for (k = n; k < 2 * n - 1; k++)
{ // 构造最优二叉树
select(HT, k, i1, i2); // 在前K-1个结点中选择权值最小的两个根结点i1和i2
HT[i1].parent = k;
HT[i2].parent = k;
HT[k].weight = HT[i1].weight + HT[i2].weight;
HT[k].lchild = i1;
HT[k].rchild = i2;
}
}
void DispHT(HTNode* HT, int n) // 显示哈夫曼树存储
{
HTNode* p;
p = HT;
cout << "k" << setw(7) << "Weight" << setw(7) << "parent"
<< setw(7) << "lchild" << setw(7) << "rchild" << endl;
for (int k = 0; k < 2 * n - 1; k++)
{
cout << k << setw(7) << (p + k)->weight << setw(7) << (p + k)->parent
<< setw(7) << (p + k)->lchild << setw(7) << (p + k)->rchild << endl;
}
}
//算法5.17 // 构建哈夫曼编码
void CreateHFCode(HTNode* HT, int n, char** HC)
{
int i, start, c, f;
char* cd;
cd = new char[n];
cd[n - 1] = '\0';
for (i = 0; i < n; i++)
{
start = n - 1;
c = i;
f = HT[i].parent;
while (f != -1)
{
if (HT[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
c = f; f = HT[f].parent;
}
cout << endl;
HC[i] = new char[n - start];
HC[i] = &cd[start];
int j = 0;
while (HC[i][j] != '\0') // 显示编码
{
cout << HC[i][j];
j++;
}
}
delete cd;
cout << endl;
}
int op;
int main()
{
int* w; // 权值数组
int n; // 权值个数
int i; // 工作变量
HTNode* HT; // 哈夫曼树
char** HC;
do
{
cout << "1-输入结点权值" << endl;
cout << "2-生成最优二叉树" << endl;
cout << "3-求哈夫曼编码" << endl;
cout << "4-退出程序" << endl;
cout << "请选择操作(1~4)";
cout << "\b\b";
cin >> op;
switch (op)
{
case 1:
cout << "测试案例" << endl;
cout << "7,5,2,3,5,6" << endl;
cout << "请输入结点的个数:";
cin >> n;
w = new int[n];
cout << "请依次输入权值:" << endl;
for (i = 0; i < n; i++)
{
cout << "请输入第" << i + 1 << "个权值:";
cin >> w[i];
}
break;
case 2:
HT = new HTNode[2 * n - 1]; // 申请最优二叉树存储空间
HuffmanTree(HT, w, n);
cout << "创建的哈夫曼树为:\n";
DispHT(HT, n);
system("pause");
break;
case 3:
HC = new char* [n]; // 存储哈示曼编码
cout << "哈夫曼编码为:\n";
CreateHFCode(HT, n, HC);
break;
case 4:
cout << "结束运行Bye-Bye!" << endl;
break;
}
} while (op != 4);
return 0;
}