【树】哈弗曼树和哈弗曼编码

#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;
}

    原文作者:哈夫曼树
    原文地址: https://blog.csdn.net/ruan875417/article/details/50511700
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞