HuffmanTree

要了解HuffmanTree,首先要了解几个概念:
1.二叉树的路径长度:从根结点到每个节点的路径长度之和。
2.带权路径长度:(从根结点到每个叶子结点的路径*每个叶子结点的权限)相加之和。
3.HuffmanTree:带权路径最小的树。
HuffmanTree的构造也用了堆的概念,在每次插入一个数据后,需要调整整棵树,来使得带权路径最小。
Heap:

#include <iostream>
#include <windows.h>
#include <vector>
#include <assert.h>
using namespace std;

template<class T>
struct Less
{
    bool operator()(const T& left, const T& right)
    {
        return left->_weight < right->_weight;
    }
};

template<class T>
struct Greater
{
    bool operator()(const T& left, const T& right)
    {
        return left->_weight > right->_weight;
    }
};

// 小堆
template<class T, class Compare = Less<T>>
class Heap
{
public:
    Heap()
    {}

    Heap(const T arr[], size_t size, const T& invalid)
    {
        _heap.resize(size);
        for(size_t i=0; i<size; ++i)//先将所有的数都放入堆中
        {
            _heap[i] = arr[i];
        }
        int root = (_heap.size()-2)>>1;//将堆中的数据向下调整
        for(; root>=0;--root)
            _AdjustDown(root);
    }
    void Insert(const T& data)
    {
        _heap.push_back(data);
        if(_heap.size() > 1)
            _AdjustUp();
    }
    void Remove()
    {
        assert(!_heap.empty());
        std::swap(_heap[0], _heap[_heap.size() - 1]);
        _heap.pop_back();
        if(_heap.size() > 1)
            _AdjustDown(0);
    }

    size_t Size()const
    {
        return _heap.size();
    }

    bool Empty()const
    {
        return 0 == _heap.size();
    }
    const T& Top()const
    {
        return _heap[0];
    }
    void _AdjustDown(size_t parent)
    {
        size_t child = parent*2+1;
        size_t size = _heap.size();
        while(child < size)
        {
            if(child+1 < size && Compare()(_heap[child+1], _heap[child]))
                child += 1;
            if(Compare()(_heap[child], _heap[parent]))
            {
                std::swap(_heap[child], _heap[parent]);
                parent = child;
                child = parent*2 + 1;
            }
            else
                return ;
        }
    }
    void _AdjustUp()
    {
        size_t child = _heap.size()-1;
        size_t parent = (child-1) >> 1;
        while(child != 0)
        {
            if(Compare()(_heap[child], _heap[parent]))
            {
                std::swap(_heap[child], _heap[parent]);
                child = parent;
                parent = (child-1) >> 1;
            }
            else
                return ;
        }
    }
private:
    std::vector<T> _heap;
};

HuffmanTree:

#include "heap.h"
template<class T>
struct HuffmanTreeNode
{
    HuffmanTreeNode(const T& weight)
        : _weight(weight)
        , _pLeft(NULL)
        , _pRight(NULL)
        , _pParent(NULL)
    {}

    T _weight;         // 权值
    HuffmanTreeNode<T>* _pLeft;
    HuffmanTreeNode<T>* _pRight;
    HuffmanTreeNode<T>* _pParent;
};


template<class T>
class HuffmanTree
{
    typedef HuffmanTreeNode<T> Node;
public:
    HuffmanTree()
        : _pRoot(NULL)
    {}

    HuffmanTree(const T arr[], size_t size, const T& invalid)
    {
        _Create(arr, size, invalid);
    }
    ~HuffmanTree()
    {
            _Destroy(_pRoot);
    }

    const Node* Root()const
    {
        return _pRoot;
    }

private:
    void _Create(const T arr[], size_t size, const T& invalid)
    {
        struct Compare
        {
            bool operator()(const Node* pLeft, const Node* pRight)
            {
                return pLeft->_weight < pRight->_weight;
            }
        };
        Heap<Node*> hp;
        for(size_t i=0; i<size; ++i)//先将所有的数都放入堆中
        {
            if(arr[i] != invalid)
                hp.Insert(new Node(arr[i]));
        }
        while(hp.Size() > 1)
        {
            Node* pLeft = hp.Top();
            hp.Remove();
            Node* pRight = hp.Top();
            hp.Remove();
            Node* pParent = new Node(pLeft->_weight + pRight->_weight);
            pLeft->_pParent = pParent;
            pRight->_pParent = pParent;
            pParent->_pLeft = pLeft;
            pParent->_pRight = pRight;
            hp.Insert(pParent);
            hp._AdjustUp();
        }
        _pRoot = hp.Top();
    }
    void _Destroy(Node* & pRoot)
    {
        if(pRoot)
        {
            _Destroy(pRoot->_pLeft);
            _Destroy(pRoot->_pRight);
            delete pRoot;
            pRoot == NULL;
        }
    }

protected:
    Node* _pRoot;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值