1.自定义的结构体和重命名的类型
using namespace std;
const int n = 8;
const int m = n * 2;
typedef unsigned int WeightType;
typedef unsigned int NodeType;
typedef struct {
WeightType wight;
NodeType parent, leftchild, rightchild;
} HTNode;
typedef HTNode HuffmanTree[m];
struct IndexWeight {
int index;
WeightType wh;
operator WeightType() const { return wh; }
};
我们给了八个叶子结点(根据自己需要给),然后构成哈夫曼树的话一共要2*n(n是叶子结点的个数)。之后我们将权值为int型,即第四行,构成表的时候需要父节点和孩子结点,也为int,之后的结构体是每一个结点的信息。下面就是构造节点数组(类似于二维数组),最后的结构体是我们用来将当前节点和未使用节点做排序,使用C++stl库中的数据结构模板queue。
2.打印表的函数
void PrintHuffmanTree(HuffmanTree hft) {
for (int i = 0; i < m; ++i) {
printf("index=%d,weight=%d,parent=%d,lchild=%d,rchild=%d\n", i,
hft[i].wight, hft[i].parent, hft[i].leftchild, hft[i].rightchild);
}
printf("\n");
}
就是一个简单的打印函数,不做赘述。但是如果打印不整齐的话,自己家制表附和%-3d。
3.初始化哈夫曼树
void InitHuffmanTree(HuffmanTree hft, WeightType w[]) {
memset(hft, 0, sizeof(HuffmanTree));
for (int i = 0; i < n; i++) {
hft[i + 1].wight = w[i];
}
}
即将叶子节点的表初始化出来。
4.哈夫曼树的具体实现函数
void CreateHuffmanTree(HuffmanTree hft) {
priority_queue<IndexWeight, vector<IndexWeight>, std::greater<IndexWeight>>
qu;//将第一行介绍的结构体作为模板传入vector,greater是将权值按照从小到大的顺序入队
for (int i = 1; i <= n; i++) {
qu.push(IndexWeight{i, hft[i].wight});
}//将叶子节点当前节点位置和权值加入到vector内,push函数即入队
int k = n + 1;//当前加节点的位置
while (!qu.empty()) {//循环条件必须队不为空
if (qu.empty())
break;
IndexWeight left = qu.top();//获取当前队中最小权值,同样得队不为空
qu.pop();//当前元素出队
if (qu.empty()) {
break;
}
IndexWeight right = qu.top();//获取当前队中最小权值,寄此次循环开始是队中第二小的元素,进入条件队不为空
qu.pop();//元素出队
hft[k].wight = left.wh + right.wh;//将当前权值更改为第一小和第二小的和
hft[k].leftchild = left.index;//左孩子为第一小的权值
hft[k].rightchild = right.index;//右孩子为第二小的权值
hft[left.index].parent = k;//将左孩子的父节点更改为k+1
hft[right.index].parent = k;//同上
qu.push(IndexWeight{k, hft[k].wight});//当前元素入队
k++;
}
}
5.完整代码
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int n = 8;
const int m = n * 2;
typedef unsigned int WeightType;
typedef unsigned int NodeType;
typedef struct {
WeightType wight;
NodeType parent, leftchild, rightchild;
} HTNode;
typedef HTNode HuffmanTree[m];
struct IndexWeight {
int index;
WeightType wh;
operator WeightType() const { return wh; }
};
void CreateHuffmanTree(HuffmanTree hft) {
priority_queue<IndexWeight, vector<IndexWeight>, std::greater<IndexWeight>>
qu;
for (int i = 1; i <= n; i++) {
qu.push(IndexWeight{i, hft[i].wight});
}
int k = n + 1;
while (!qu.empty()) {
if (qu.empty())
break;
IndexWeight left = qu.top();
qu.pop();
if (qu.empty()) {
break;
}
IndexWeight right = qu.top();
qu.pop();
hft[k].wight = left.wh + right.wh;
hft[k].leftchild = left.index;
hft[k].rightchild = right.index;
hft[left.index].parent = k;
hft[right.index].parent = k;
qu.push(IndexWeight{k, hft[k].wight});
k++;
}
}
void PrintHuffmanTree(HuffmanTree hft) {
for (int i = 0; i < m; ++i) {
printf("index=%d,weight=%d,parent=%d,lchild=%d,rchild=%d\n", i,
hft[i].wight, hft[i].parent, hft[i].leftchild, hft[i].rightchild);
}
printf("\n");
}
void InitHuffmanTree(HuffmanTree hft, WeightType w[]) {
memset(hft, 0, sizeof(HuffmanTree));
for (int i = 0; i < n; i++) {
hft[i + 1].wight = w[i];
}
}
int main() {
WeightType w[] = {5, 29, 7, 8, 14, 23, 3, 11};
HuffmanTree hft = {0};
InitHuffmanTree(hft, w);
PrintHuffmanTree(hft);
CreateHuffmanTree(hft);
PrintHuffmanTree(hft);
}