软件设计师-第三章-构建哈夫曼树

一、思路
  • 哈夫曼树目标建立一棵权值最小的树。
  • 每次选取两个权值较小的结点作为左右子树构造一棵新的二叉树,置新构造的二叉树的权值为左右子树的权值之和。
  • 将新构造的这棵二叉树作为我们的选取的一部分。

因为选取最小两个权值,可以用到堆,可以方便的获得最小值

C++中的堆是优先队列 priority_queue
需引用头文件#include<queue>

二、代码
#include<iostream>
#include<queue>

using namespace std;

typedef struct node{
    int w;
    struct node *lchild;
    struct node *rchild;
    node(int W){
        w = W;
        lchild = NULL;
        rchild = NULL;
    }
}TreeNode;

//堆中存储结构体类型,需手写排序
struct cmp{
    bool operator ()(TreeNode* a, TreeNode* b){
        return a->w > b->w;
    }
};

int n;// 树节点个数
priority_queue<TreeNode*, vector<TreeNode*>, cmp> heap;//定义小根堆

void fastRead(){
    ios::sync_with_stdio();
    cin.tie();
}

void preorder(TreeNode* root){
    if(!root) return;
    cout << root->w << ' ';
    preorder(root->lchild);
    preorder(root->rchild);
}

void inorder(TreeNode* root){
    if(!root) return;
    inorder(root->lchild);
    cout << root->w << ' ';
    inorder(root->rchild);
}

void postorder(TreeNode* root){
    if(!root) return;
    inorder(root->lchild);
    inorder(root->rchild);
    cout << root->w << ' ';
}

void print(TreeNode* root){
    puts("哈夫曼树前/中/后序序列:");
    preorder(root);//前序输出哈夫曼树
    puts("");
    inorder(root);//中序输出哈夫曼树
    puts("");
    postorder(root);//后序输出哈夫曼树
    puts("");
}

int main(){
    
    fastRead();
    cin >> n;

    for(int i = 0; i < n; i++){
        int w; cin >> w;
        TreeNode* tmpNode = new TreeNode(w);
        heap.push(tmpNode);
    }
    
    /*-------------建立哈夫曼树过程-------------*/
    while(heap.size() >= 2){
        
        auto l = heap.top(); heap.pop();
        auto r = heap.top(); heap.pop();
        auto tmp_parent = new TreeNode(l->w + r->w);
        tmp_parent->lchild = l;
        tmp_parent->rchild = r;
        heap.push(tmp_parent);
    }
    /*------------------------------------------*/
    TreeNode* root = heap.top();
    
    print(root);
    
    return 0;
}
/*
Test Case:
8
2 3 6 7 10 19 21 32
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值