数据结构——哈夫曼树实现

来源:互联网 发布:低周波按摩仪 知乎 编辑:程序博客网 时间:2024/06/01 21:44

利用小堆实现哈夫曼树

Heap.h

#pragma once#include <vector>#include <assert.h>//仿函数template<class T>struct Less{    bool operator()(const T& left,const T& right)    {        return left < right;    }};template<class T>struct Greater{    bool operator()(const T& left,const T& right)    {        return left > right;    }};template<class T,class Compare = Less<T>>class Heap{public:    Heap()    {}    Heap(const T array[],size_t size)    {        _heap.resize (size);        for(int i=0;i<size;i++)        {            //_heap.push_back (array[i]);            _heap[i] = array[i];        }        int root = (_heap.size ()-2)>>1;        for(;root>=0;root--)        {            _AdjustDown(root);        }    }    size_t Size()const    {        return _heap.size ();    }    bool Empty()const    {        return _heap.empty ();    }    void Insert(const T& data)    {        //先尾插入元素        //再向上调整        _heap.push_back (data);        _AdjustUp(_heap.size ()-1);    }    void Remove()    {        //如果堆为空则不操作        if(_heap.size ()==0)            return ;        //如果只有根节点和其孩子则交换后直接删除最后一个节点        if(_heap.size ()<=2)        {            std::swap (_heap[0],_heap[_heap.size ()-1]);            _heap.pop_back ();        }        //如果节点数大于2个,则先交换根元素和尾元素,再删除尾元素,        //最后重新调整堆结构        else        {            std::swap (_heap[0],_heap[_heap.size ()-1]);            _heap.pop_back ();            //int root = (_heap.size ()-2)>>1;            //for(;root>=0;root--)            //  _AdjustDown(root);            int child = _heap.size ()-1;            _AdjustUp(child);        }    }    const T& Top()const    {        assert(!Empty());        return _heap[0];    }private:    void _AdjustDown(size_t parent)    {        size_t child = parent*2+1;        while(child<_heap.size ())        {            Compare com;            //如果右孩子存在则找左右孩子中最小的节点            if(child+1<_heap.size () && com(_heap[child+1],_heap[child]))                child+=1;            if(com(_heap[child],_heap[parent]))            {                std::swap (_heap[parent],_heap[child]);                parent = child;                child = parent*2+1;            }            else                return ;        }    }    void _AdjustUp(size_t child)    {        while(child>=1)        {            Compare com;            size_t parent = (child-1)>>1;            if(com(_heap[child],_heap[parent]))                std::swap (_heap[parent],_heap[child]);            child = parent;        }    }private:    std::vector <T> _heap;};

Huffman.h

#pragma once#include "Heap.h"#include <assert.h>using namespace std;template<class T>struct Node{    Node(const T& weight)        :_weight(weight)        ,_pLeft(NULL)        ,_pRight(NULL)    {}    T _weight;    T _data;    Node<T>* _pLeft;    Node<T>* _pRight;};template<class T>class HuffmanTree{public:    HuffmanTree()        :_pRoot(NULL)    {}    HuffmanTree(const T array[],size_t size)    {        _Create(array,size);    }       private:    void _Create(const T array[],size_t size)    {        assert(array);        struct CompareNode        {            bool operator()(Node<T>* left,Node<T>* right)            {                return left->_weight < right->_weight;            }        };        Heap<Node<T>*,CompareNode> hp;        for(int i=0;i<size;i++)        {            Node<T>* node = new Node<T>(array[i]);            hp.Insert (node);        }        while(hp.Size()>1)        {            Node<T>* pLeft = hp.Top ();            hp.Remove ();            Node<T>* pRight = hp.Top ();            hp.Remove ();            Node<T>* parent = new Node<T>(pLeft->_weight+pRight->_weight);            parent->_pLeft = pLeft;            parent->_pRight = pRight;            hp.Insert (parent);        }        _pRoot = hp.Top();    }private:    Node<T>* _pRoot;};
原创粉丝点击