1. 程式人生 > >資料結構——哈夫曼樹實現

資料結構——哈夫曼樹實現

利用小堆實現哈夫曼樹

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;
};