哈夫曼树实现

哈夫曼树的基本概念

路径:从树中结点到另一个结点之间的分支构成这两个结点间的路径

结点的路径长度:两结点间路径上的分支数
树的路径长度:从树根到每一个结点的路径长度之和。记作:TL
权:将树中结点赋给一个有着某种特殊意义的值,则这个数值称为该结点的权

结点的带权路径长度:从根结点出发到该节点之间的路径长度与该结点的权的乘积

树的带权路径长度:树中所有叶子结点带权路径长度之和
哈夫曼树:最优树(带权路径长度(WPL)最短的树)

哈夫曼树的特点

满二叉树不一定是哈夫曼树
哈夫曼树中权值越大的叶子离根越近
具有相同带权结点的哈夫曼树不唯一

哈夫曼树的一些知识点
  • 包含n个叶子结点的哈夫曼树共有2n-1个结点
  • 哈夫曼树的结点的度为0和2,没有度为1的结点
  • 包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个新结点
哈夫曼树构造算法的实现
定义结构体
typedef struct{
	int weight;
	int parent,lch,rch;
}HTNode,*HuffmanTree;
算法实现

void Select(HuffmanTree &ht, int i, int &s1, int &s2) {
    int min = INT32_MAX;
    for (int j = 1; j <=i; ++j) {
        for (int k = 1; k <=i; ++k) {
            int temp = ht[j].weight + ht[k].weight;
            if (k != j && ht[j].parent == 0 && ht[k].parent == 0) {
                if (temp < min) {
                    min = temp;
                    s1 = j;
                    s2 = k;

                }
            }
        }
    }
}

void createHuffmanTree(int n) {
    int m = 2 * n - 1;
    HuffmanTree ht = new HTNode[m + 1];
    for (int i = 1; i <= m; ++i) {
        ht[i].parent = ht[i].lch = ht[i].rch = 0;
    }
    for (int j = 1; j <= n; ++j) {
        cin >> ht[j].weight;
    }
    for (int k = n + 1; k <= m; ++k) {
        int s1, s2;
        Select(ht, k - 1, s1, s2); // 取权值相加最小的两个结点
        ht[s1].parent = ht[s2].parent = k; // 他们俩的父节点就是构造出来的新结点(两个权值的和)
        ht[k].lch = s1; // 新结点左孩子赋值
        ht[k].rch = s2; // 新结点右孩子赋值
        ht[k].weight = ht[s1].weight + ht[s2].weight; // 权值相加
    }

    for (int l = 1; l <= m; ++l) {
        cout << "weight :" << ht[l].weight<<"  " << "parent :  "
             << ht[l].parent << "   " << "lchild: "
             << ht[l].lch << "   " << "rchild :"
             << ht[l].rch<< "   " << endl;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值