实现哈夫曼树

hufTreeNod.h

#pragma once
# include<iostream>

//权重就直接用整型吧
class hufTreeNode
{
public:
    hufTreeNode(int t=0) :weight(t) {}
    int weight;
    hufTreeNode *lChild=NULL;
    hufTreeNode *rChild=NULL;
    hufTreeNode *parent=NULL;
};

hufTree.h

#pragma once
# include<vector>
# include"hufTreeNode.h"
# include<algorithm>
# include<map>
using namespace std;

class hufTree
{
public:
    hufTree() = default;//默认构造函数
    void input();//输入节点权重,比如输入3,4,6,5,9
    void create(vector<int> &i);//构造哈夫曼树
    vector<int> & getVec() { return i; }
    ~hufTree()
    {
        delete []node;
        delete[]parent;
    }
private:
    hufTreeNode *root;//根节点
    vector<int> vec;//保存输入的节点权重
    vector<int> i;//iVec的副本
    int numOfNode;
    hufTreeNode* parent;//构造的哈夫曼树中度为2的节点个数
    hufTreeNode* node;//度为0的节点个数
    map<int, hufTreeNode*> m;
};

void hufTree::input()
{
    int elem;

    while (cin >> elem)
    {
        vec.push_back(elem);
    }
    sort(vec.begin(), vec.end());
    i = vec;

    numOfNode = vec.size();
    parent = new hufTreeNode[numOfNode - 1];//一颗二叉树中,度为2的节点的个数为度为0的节点
                                            //的个数-1
    node = new hufTreeNode[numOfNode];
    root = &parent[numOfNode - 2];
}

void hufTree::create(vector<int> &i)
{
    static int iCount = 1;//第一次处理,一共要执行numOfNode-1次
    static int iCount1 = 0;
    /*
    比如输入序列3,4,6,5,9
    iVec保存该序列,然后将权重最小的两个节点合并,在i中删除第一个元素,将第二个元素改为合并之后的,
    然后排序,递归调用
    */

    int ch1 = *i.begin();
    int ch2 = *(i.begin() + 1);
    int par = ch1 + ch2;
    map<int, hufTreeNode*>::iterator it1 = m.find(ch1);
    map<int, hufTreeNode*>::iterator it2 = m.find(ch2);
    if(ch1==ch2)
        it2=m.end();
    if (it1 != m.end() && it2 != m.end())//i中第一,二元素均在parent中
    {
        m[ch1]->parent = &parent[iCount - 1];
        m[ch2]->parent = &parent[iCount - 1];

        parent[iCount - 1].lChild = m[ch1];
        parent[iCount - 1].rChild = m[ch2];
        parent[iCount - 1].weight = par;

        m[par] = &parent[iCount - 1];
    }
    else if (it1 != m.end() && it2 == m.end())//第一个元素在parent中,第二个不在
    {
        iCount1++;
        m[ch1]->parent = &parent[iCount - 1];
        node[iCount1 - 1].weight = ch2;
        node[iCount1 - 1].parent = &parent[iCount - 1];

        parent[iCount - 1].lChild = m[ch1];
        parent[iCount - 1].rChild = &node[iCount1-1];
        parent[iCount - 1].weight = par;

        m[par] = &parent[iCount - 1];

    }

    else if (it1 == m.end() && it2 != m.end())//第一个元素不在parent中,第二个在
    {
        iCount1++;
        m[ch2]->parent = &parent[iCount - 1];
        node[iCount1 - 1].weight = ch1;
        node[iCount1 - 1].parent = &parent[iCount - 1];

        parent[iCount - 1].lChild = m[ch2];
        parent[iCount - 1].rChild = &node[iCount1 - 1];
        parent[iCount - 1].weight = par;

        m[par] = &parent[iCount - 1];

    }

    else
    {
        iCount1 += 2;
        node[iCount1 - 2].weight =ch1;
        node[iCount1 - 2].parent = &parent[iCount - 1];
        node[iCount1-1].weight = ch2;
        node[iCount1-1].parent = &parent[iCount - 1];

        parent[iCount - 1].lChild = &node[iCount1 - 2];
        parent[iCount - 1].rChild = &node[iCount1-1];
        parent[iCount - 1].weight = par;

        m[par] = &parent[iCount - 1];

    }

    vector<int>::iterator p = i.begin();
    i.erase(p);//删除最小的一个元素,比如之前是3,4合并为7,就删除3,把4改为7,排序
    *i.begin() = parent[iCount - 1].weight;
    sort(i.begin(), i.end());
    ++iCount;
    if(i.size()>1)
    create(i);
    else
    {
        root = &parent[numOfNode - 2];
        int i;
        return;
    }
}

main.cpp

# include<iostream>
# include"hufTreeNode.h"
# include"hufTree.h"

using namespace std;
int main()
{
    hufTree myhufTree;
    myhufTree.input();
    myhufTree.create(myhufTree.getVec());
    system("pause");
    return 0;
}

可以测试一下,比如序列3,4,5,6
这里写图片描述
构造的哈夫曼树应该是这样,对吧?
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值