一、概述
霍夫曼树(Huffman Tree)是二叉树的一种,可以从中延伸出霍夫曼编码,利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行移码(复原),是一个很有应用价值的手段。
在数据结构中,霍夫曼编码也是数形结构的实际应用之一,对于初学者,编码较有难度。
二、代码
1、预处理
为了遍历方便,这里选择使用顺序储存结构,建立结构体如下:
#define _CRT_SECURE_NO_WARNINGS 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char character; //值
int frequency; //权重(频率)
int parent, left, right; //父节点,左右子节点
} HuffmanNode;//霍夫曼树节点
typedef struct {
char character;//值
char code[256];//霍夫曼编码
} CodeTable;//对应表
创造全局变量如下:
HuffmanNode huffmanTree[100];//建立节点数组
CodeTable codeTable[256];//建立霍夫曼编码数组
int nodeCount = 0;//节点数
2、创建霍夫曼树
根据霍夫曼树的逻辑可知,我们需要寻找所有的节点中频率最小的两个值来创造新的节点,所以,我们需要一个函数来解决这个问题。
void selectTwoSmallest(int n, int* smallest1, int* smallest2) {
int min1 = 10000000, min2 = 10000000;
*smallest1 = *smallest2 = -1;
for (int i = 0; i < n; i++) {
if (huffmanTree[i].parent == -1) {
if (huffmanTree[i].frequency < min1) {
min2 = min1;
*smallest2 = *smallest1;
min1 = huffmanTree[i].frequency;
*smallest1 = i;
}
else if (huffmanTree[i].frequency < min2) {
min2 = huffmanTree[i].frequency;
*smallest2 = i;
}
}
}
}
这个函数中,n为现有节点数,smallest1,smallest2是最小节点索引,min1为最小值,min2为次小值。
依次遍历各个节点,通过if判断是否为没有父节点的节点,因为只有没有父节点的树叶才考虑生成新节点,与最小值比较,若更小,则交换为最小值,前最小值成为次小值,若不小,则与次小值比较,并根据实际情况决定是否调换。最终smallest1,smallest2是最小的索引,返回到树生成函数下生成新节点。
voi