编写一个程序构建哈夫曼树和生成哈夫曼树
时间: 2024-05-14 13:10:56 浏览: 168
哈夫曼树是一种用于数据压缩的二叉树,通过统计字符出现的频率构建哈夫曼树,可以实现对数据进行高效压缩。
下面是构建哈夫曼树的基本步骤:
1. 统计字符出现的频率。
2. 将每个字符看做一个节点,将这些节点按照频率从小到大排序。
3. 取出频率最小的两个节点,将它们合并为一个新节点,新节点的频率为两个节点的频率之和,将新节点插入到排序后的节点序列中。
4. 重复步骤3,直到只剩下一个节点,即为哈夫曼树的根节点。
下面是生成哈夫曼编码的基本步骤:
1. 从哈夫曼树的根节点开始遍历,如果走左子树就在当前的编码后面添加0,如果走右子树就在当前的编码后面添加1。
2. 如果遍历到了叶子节点,就将该节点对应的字符及其编码存储起来。
3. 重复步骤1和2,直到遍历完整棵哈夫曼树。
相关问题
编写一个c语言程序构建哈夫曼树并生成哈夫曼树
哈夫曼树是一种带权路径长度最小的二叉树,常用于数据压缩和加密等领域。下面是构建哈夫曼树并生成哈夫曼编码的C语言程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_SIZE 100
// 定义哈夫曼树结点
typedef struct
{
int weight; // 结点权重
int parent; // 父结点下标
int lchild; // 左子结点下标
int rchild; // 右子结点下标
} HTNode, *HuffmanTree;
// 定义哈夫曼编码结构体
typedef char **HuffmanCode;
// 构建哈夫曼树
void CreateHuffmanTree(HuffmanTree *HT, int n)
{
if (n <= 1)
{
return;
}
int m = 2 * n - 1; // 哈夫曼树结点数
*HT = (HuffmanTree) malloc((m + 1) * sizeof(HTNode)); // 分配哈夫曼树内存空间
// 初始化哈夫曼树,将前n个结点的权重读入到哈夫曼树的叶子结点中
for (int i = 1; i <= n; i++)
{
scanf("%d", &(*HT)[i].weight);
(*HT)[i].parent = 0;
(*HT)[i].lchild = 0;
(*HT)[i].rchild = 0;
}
// 构建哈夫曼树,每次找到权重最小的两个结点合并成一个新的结点,直到只剩一个结点
for (int i = n + 1; i <= m; i++)
{
int s1 = 1, s2 = 2;
while ((*HT)[s1].parent != 0)
{
s1++;
}
while ((*HT)[s2].parent != 0)
{
s2++;
}
// 找到权重最小的两个结点s1和s2
for (int j = 1; j < i; j++)
{
if ((*HT)[j].parent == 0)
{
if ((*HT)[j].weight < (*HT)[s1].weight)
{
s2 = s1;
s1 = j;
}
else if ((*HT)[j].weight < (*HT)[s2].weight)
{
s2 = j;
}
}
}
// 合并s1和s2为新的结点i
(*HT)[s1].parent = i;
(*HT)[s2].parent = i;
(*HT)[i].lchild = s1;
(*HT)[i].rchild = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
}
// 生成哈夫曼编码
void HuffmanCoding(HuffmanTree HT, HuffmanCode *HC, int n)
{
*HC = (HuffmanCode) malloc((n + 1) * sizeof(char *));
char *cd = (char *) malloc(n * sizeof(char));
cd[n - 1] = '\0';
for (int i = 1; i <= n; i++)
{
int start = n - 1;
int c = i;
int f = HT[i].parent;
while (f != 0)
{
if (HT[f].lchild == c)
{
cd[--start] = '0';
}
else
{
cd[--start] = '1';
}
c = f;
f = HT[c].parent;
}
(*HC)[i] = (char *) malloc((n - start) * sizeof(char));
strcpy((*HC)[i], &cd[start]);
}
free(cd);
}
int main()
{
int n;
printf("请输入哈夫曼树叶子结点个数:\n");
scanf("%d", &n);
HuffmanTree HT;
HuffmanCode HC;
printf("请依次输入各个叶子结点的权重:\n");
CreateHuffmanTree(&HT, n);
HuffmanCoding(HT, &HC, n);
printf("哈夫曼编码如下:\n");
for (int i = 1; i <= n; i++)
{
printf("%d: %s\n", HT[i].weight, HC[i]);
}
return 0;
}
```
以上代码通过输入哈夫曼树叶子结点个数和各个叶子结点的权重来构建哈夫曼树,并生成对应的哈夫曼编码。
用Python代码实现编写一个程序,构造哈夫曼树和哈夫曼编码,要求输出建立的哈夫曼树和相关的哈夫曼编码
好的,以下是Python代码实现哈夫曼树和哈夫曼编码的程序:
```
class Node:
def __init__(self, value, freq):
self.value = value
self.freq = freq
self.left = None
self.right = None
def build_huffman_tree(characters, freqs):
nodes = []
for i in range(len(characters)):
node = Node(characters[i], freqs[i])
nodes.append(node)
while len(nodes) > 1:
nodes = sorted(nodes, key=lambda x: x.freq)
left_node = nodes.pop(0)
right_node = nodes.pop(0)
parent_node = Node(None, left_node.freq + right_node.freq)
parent_node.left = left_node
parent_node.right = right_node
nodes.append(parent_node)
return nodes[0]
def build_huffman_code(node, current_code, huffman_code):
if node is None:
return
if node.value is not None:
huffman_code[node.value] = current_code
return
build_huffman_code(node.left, current_code + "0", huffman_code)
build_huffman_code(node.right, current_code + "1", huffman_code)
# Test example
characters = ['a', 'b', 'c', 'd', 'e', 'f']
freqs = [45, 13, 12, 16, 9, 5]
huffman_code = {}
root_node = build_huffman_tree(characters, freqs)
build_huffman_code(root_node, "", huffman_code)
print("Huffman tree:")
print("Root node frequency:", root_node.freq)
print("Left sub-tree frequency:", root_node.left.freq)
print("Right sub-tree frequency:", root_node.right.freq)
print("\nHuffman codes:")
for char, code in huffman_code.items():
print(char, ":", code)
```
程序输入两个列表: `characters` 和 `freqs`,分别表示字符和对应的频率。程序首先将每个字符和其对应的频率封装为节点对象,并将这些节点添加到一个列表中。然后,程序循环执行以下步骤:
1. 对节点列表按照频率排序。
2. 从节点列表中弹出两个频率最小的节点,并合并这两个节点,构造一个父节点。
3. 将该父节点添加到节点列表中。
4. 重复步骤 1-3 直至只剩下一个节点,该节点就是哈夫曼树的根节点。
接着,程序调用 `build_huffman_code` 函数构建哈夫曼编码。该函数使用先序遍历方式遍历哈夫曼树,对每个叶子节点生成一个Huffman编码,Huffman编码是由0和1组成的字符串,左子树的节点得到的编码为0,右子树的节点得到的编码为1。
最后,程序输出构建的哈夫曼树信息和生成的哈夫曼编码信息。
阅读全文