哈夫曼树及哈夫曼编码(哈夫曼编码为string实现)
#include<iostream>
#include<string>
#include <algorithm>
using namespace std;
//luosansui
struct Huffman{
int weight;
int father;
int left;
int right;
char tip;
Huffman() {
weight = 0;
father = 0;
left = 0;
right = 0;
tip = '1';
}
};
//求数组长度
template<class T>
int length(T& data) {
return sizeof(data) / sizeof(data[0]);
}
//选出最小的数
int m_selectMin(int index, Huffman* head, int n) {
int min = n;
for (int i = 1; i < n+1; i++){
if (head[i].tip != '0' && i != index) {//&& head[i].weight > head[min].weight
min = i;
break;//
}
}
for(int i = 1; i < n+1; i++) {
if (head[i].tip != '0' && i != index && head[i].weight <= head[min].weight) {
min = i;
}
}
return min;
}
//构建哈夫曼树
Huffman* createTree(int weight_arr[], int n) {
Huffman* head = new Huffman[n * 2];
for (int i = 1; i < n + 1; i++) {
head[i].weight = weight_arr[i - 1];
}
int min_index_1 = -1, min_index_2 = -1;
int indexn = n;
//最小的两个权值,挑选n-1次
for (int i = 1; i < n; i++) {
//挑选第一个最小的
min_index_1 = m_selectMin(-1, head, indexn);
//挑选第二个最小的
min_index_2 = m_selectMin(min_index_1, head, indexn);
//生成树
if (head[min_index_1].left == 0 && head[min_index_1].right == 0 && head[min_index_2].left != 0) {
int tem = min_index_1;
min_index_1 = min_index_2;
min_index_2 = tem;
}//构建完全二叉树,可删去
head[n + i].left = min_index_1;
head[n + i].right = min_index_2;
head[n + i].weight = head[min_index_1].weight + head[min_index_2].weight;
head[min_index_1].father = n + i;
head[min_index_2].father = n + i;
//去除两个比较过的,将新的加进去
head[min_index_1].tip = '0';
head[min_index_2].tip = '0';
indexn++;
}
cout << "weight" << "\t" << "father" << "\t " << "left" << "\t " << "right" << "\t" << endl;
for (int i = 1; i < 2*n; i++) {
cout<< head[i].weight <<"\t"<< head[i].father<<"\t "<< head[i].left<< "\t" << head[i].right << "\t"<< endl;
}
return head;
}
//哈夫曼编码
void hCode(Huffman* tree,int n) {
string* code = new string[n]();
for (int i = 1; i < n+1; i++){
int k = i;
while (tree[k].father != 0){
if (k == tree[tree[k].father].left) {
code[i - 1] += "0";
}else {
code[i - 1] += "1";
}
k = tree[k].father;
}
reverse(code[i - 1].begin(), code[i - 1].end());
}
for (int i = 0; i < n; i++){
cout<<code[i]<<" ";
}
delete[] code;
}
int main(){
int arr[] = { 10,5,21,18,8,13};
Huffman* tree = createTree(arr,length(arr));
hCode(tree,length(arr));
delete[] tree;
}
求数组长度这块,貌似把数组名传入函数以后sizeof()就变成求指针的大小了。除了
template<class T>
int length(T& data) {
return sizeof(data) / sizeof(data[0]);
}
之外,暂时没想到其他办法。