C语言 哈夫曼树编码、译码、输出。

哈夫曼树的知识点概述网上有很多了,就不再补充,主要是分享一下自己对一道题的解题思路。
在这里插入图片描述
在这里插入图片描述

概述:构建哈夫曼树时,先用下标模拟数组,从叶子结点开始往上构建完整棵哈夫曼树。但和普通二叉树不同,叶子结点在1-n (0号位不用,n为输入的字符个数),根结点在 2n-1 ,其他位置为构造出的中介结点。
在这里插入图片描述

虽然哈夫曼树构建好了,很多操作树的方法得依赖于下标模拟的指针实现,每次方法调用的参数都得传入整个结构体数组。所以在构建时,多定义一个结构体指针。构建好哈夫曼树之后,每次操作树的时候可以通过传入树根的指针,当作一棵普通的二叉树来操作整棵树。(详细代码在哈夫曼树构建。)

(笔者第一次写博客,内容难免有些浅显或错误之处,还请大家指出一起探讨,共勉。)

走个流程。

1. 树结点结构体。
二叉树可以用下标模拟指针(属性 L、R),也可以自己定义结构体指针(LChild、RChild)。这里笔者为了方便后面的先序输出哈夫曼树存储的字符,就定义了结构体指针。

#define M N * 2 - 1   // 30个字符,计算可得出总节点个数。
#define N 30          // 叶子节点个数。假设最多输入30个字符。
#define MAX 999
// 哈夫曼树结构体。
typedef struct tree {
   
    char ch;         // 字符。
    double weight;   // 权重。
    int parent;     // 父结点。
    int L, R;        // 左右子树的下标。
    struct tree *LChild;	// 左孩子结点指针。
    struct tree *RChild;	// 右孩子结点指针。
    char hashcode[N];   // 字符的哈希编码。
    int is_leaves;		// 是否是叶子结点标记。
} tree, Htree[M];		// tree 是单个结点,Htree 是结构体数组。

2. 哈夫曼树构建。

// 选择最小权重的两个节点
// 具体代码实现大同小异。找出权重最小的两个结点,标记下标位置,再修改父亲结点参数,下次不再进行参与比较排序。
void Select(Htree ht, int n, int *s1, int *s2) {
   
    int i;
    double min1 = MAX, min2 = MAX;
    *s1 = 0;
    *s2 = 0;
    for (i = 1; i <= n; i++) {
   
        if (ht[i].parent == 0) {
   
            if (ht[i].weight < min1) {
   
                min2 = min1;
                *s2 = *s1;
                min1 = ht[i].weight;
                *s1 = i;
            } else if (ht[i].weight < min2) {
   
                min2 = ht[i].weight;
                *s2 = i;
            }
        }
    }
}

// 构建哈夫曼树
void crateHtree(Htree ht, int n) {
   
    int i;
    // 初始化叶子节点。
    // 叶子结点从1-n。(0号位不用)
    char s[10];
    for (i = 1; i <= n; i++) {
   
        ht[i].parent = 0;
        ht[i].L = 0;
        ht[i].R = 0;
        ht[i].is_leaves = 1;
        ht[i].RChild = NULL;
        ht[i].LChild = NULL;
    }
    // 初始化树的非叶子节点。 n+1项开始。
    for (i = n + 1; i <= 2 * n - 1; i++) {
   
        ht[i].weight = 0;
        ht[i].parent = 0;
        ht[i].L = 0;
        ht[i].R = 0;
        ht[i].is_leaves = 0;	
        ht[i].RChild = NULL;
        ht[i].LChild = NULL;
    }
    // 开始构建哈夫曼树。
    // 和平时的构建树方法不同,从下往上构建,新的结点为现有结点的父亲结点,新结点的左右孩子指针指向原有参与构建的两个结点。
    int s1
  • 20
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值