#include<iostream>
#include<iomanip>
using namespace std;
const int max_size = 50;
struct HuffmanNode{
int weight;//weight表示权值数据域
int parent;//par=0表明结点是独立的,par>0为它的双亲下标
int lchild, rchild;//lchild, rchild为左右孩子结点在数组中的下标,0则表示它是独立结点
HuffmanNode() :weight(0), parent(0), lchild(0), rchild(0){}
};
class HuffmanTree{
public:
HuffmanTree(int n);
void create_huffman_tree();
void print_huffman_tree();
void print_huffman_code();
private:
HuffmanNode huff[max_size];//保存二叉树结点的数组
int num_of_nodes;//最初权值(叶子)的个数
};
HuffmanTree::HuffmanTree(int n):num_of_nodes(n){}
void HuffmanTree::create_huffman_tree(){
int i, j;
int first_min, second_min;
int first_index, second_index;
for (int i = 0; i < num_of_nodes; i++){
cout << "权值:";
cin >> huff[i].weight;
}
for (i = 0; i < num_of_nodes - 1; i++){ //n个结点需要合并n-1次
first_min = second_min = 100000;//first_min代表最小权值,second_min代表次小权值,初值设得足够大
first_index = second_index = -1;//first_index,second_index为最小权值,次小权值的下标号
for (j = 0; j < num_of_nodes + i; j++){
if (huff[j].weight < first_min&&huff[j].parent == 0){
second_min = first_min;
first_min = huff[j].weight;
second_index = first_index;
first_index = j;
}else if (huff[j].weight < second_min&&huff[j].parent == 0){
second_min = huff[j].weight;
second_index = j;
}
}
huff[num_of_nodes + i].weight = first_min + second_min;
huff[first_index].parent = huff[second_index].parent = num_of_nodes + i;
huff[num_of_nodes + i].lchild = first_index;//为新的结点置孩子标记,左孩子为较小权值
huff[num_of_nodes + i].rchild = second_index;//为新的结点置孩子标记,右孩子为较大权值
}
}
void HuffmanTree::print_huffman_tree(){
cout << "\n" << "序号" << setw(5) << "权值" << setw(15) << "双亲的下标" << setw(15) << "左孩子的下标" << setw(15) << "右孩子的下标";
for (int j = 0; j<2 * num_of_nodes - 1; j++) //共有2*n-1个结点
cout << "\n" << j << setw(6) << huff[j].weight<< setw(15) << huff[j].parent << setw(15) << huff[j].lchild << setw(15) << huff[j].rchild << endl;
}
void HuffmanTree::print_huffman_code(){
int i, j;
int cur_index, parent_index;
int last;
char** huffman_code = new char*[num_of_nodes];
for (i = 0; i < num_of_nodes; i++)
huffman_code[i] = new char[num_of_nodes];
char* temp=new char[num_of_nodes];
for (i = 0; i < num_of_nodes; i++){ //对每个权值(叶子)编码
temp[num_of_nodes-1] = '\0';
for (j = 0; j < num_of_nodes-1; j++)
temp[j] = ' ';
last = num_of_nodes - 1;
cur_index = i; //当前结点的下标
parent_index = huff[cur_index].parent; //当前结点的双亲下标
while (parent_index!=0){//当parent_index=0则表示已经回溯到根结点了
--last;
if (huff[parent_index].lchild == cur_index)//在哈夫曼树中令所有左分支取编码为0,令所有右分支取编码为1
temp[last] = '0';
else if (huff[parent_index].rchild == cur_index)
temp[last] = '1';
cur_index = parent_index;
parent_index = huff[cur_index].parent;
}
strcpy(huffman_code[i], temp);
}
cout << "\n 权值 编码";
for (i = 0; i<num_of_nodes; i++)
cout << "\n" << setw(6) << huff[i].weight << setw(8) << huffman_code[i];
delete temp;
for (i = 0; i < num_of_nodes; i++)
delete[] huffman_code[i];
delete[] huffman_code;
}
int main(){
int num;
cout << "输入的权值个数:n=?";
cin >> num;
HuffmanTree huffman_tree(num);
huffman_tree.create_huffman_tree();
huffman_tree.print_huffman_tree();
huffman_tree.print_huffman_code();
return 0;
}
【树】哈弗曼树和哈弗曼编码
最新推荐文章于 2025-05-20 18:44:14 发布