7-1 A. DS二叉树--赫夫曼树的构建与编码

题目描述

给定n个权值,根据这些权值构造huffman树,并进行huffman编码

大家参考课本算法6.12为主,注意数组访问是从位置1开始

要求:赫夫曼的构建中,默认左孩子权值不大于右孩子权值

输入

第一行先输入n,表示有n个权值,即有n个叶子

第二行输入n个权值,权值全是小于1万的正整数

输入样例:

5
15 4 4 3 2

输出

逐行输出每个权值对应的编码,格式如下:权值-编码
即每行先输出1个权值,再输出一个短划线,再输出对应编码

接着下一行输出下一个权值和编码,以此类推

输出样例:

15-1
4-010
4-011
3-001
2-000

思路

以样例为例:

代码

#include <iostream>
using namespace std;

struct Node{
    int weight;
    int parent;
    int lchild;
    int rchild;
};

class HuffmanTree{
    Node *list;
    int n,m1,m2;
public:
    HuffmanTree(){  //初始化,制表
        cin >> n;
        list = new Node[2*n];
        for(int i = 1; i < 2*n; i++){
            if(i >= 1 && i <= n){  //记录给定的权重
                cin >> list[i].weight;
            }else{
                list[i].weight = 0;
            }
            list[i].parent = 0;
            list[i].lchild = 0;
            list[i].rchild = 0;
        }
    }

    void makeTree(){  //计算表格
        int k = n+1;
        while(k < 2*n){
            getMin(k);
            list[k].weight = list[m1].weight + list[m2].weight;
            list[k].lchild = m1;
            list[k].rchild = m2;
            list[m1].parent = k;
            list[m2].parent = k;
            k++;
        }
    }

    void getMin(int k){  //获取每次合并后的最小的两个数及其下标
        int min1 = 9999;
        int min2 = 9999;
        m1 = 0, m2 = 0;
        for(int i = 1; i < k; i++){
            int temp = list[i].weight;
            if(list[i].parent == 0 && temp < min2){
                if(temp >= min1){
                    min2 = temp;
                    m2 = i;
                }else{
                    min2 = min1;
                    min1 = temp;
                    m2 = m1;
                    m1 = i;
                }
            }
        }
    }

    void getCode(){  //计算编码
        for(int i = 1; i <= n; i++){
            string s = "";
            int v = i, flag = i;
            while(list[v].parent != 0){
                v = list[v].parent;
                if(list[v].lchild == flag){
                    s = "0"+s;
                }else{
                    s = "1"+s;
                }
                flag = v;
            }
            cout << list[i].weight << "-" << s << endl;
        }
    }
};

int main()
{
    HuffmanTree tree;
    tree.makeTree();
    tree.getCode();
    return 0;
}
  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值