template class Hufftree { public: template Hufftree(InputIterator begin, InputIterator end); ~Hufftree() { delete tree; } template std::vector encode(InputIterator begin, InputIterator end); std::vector encode(DataType const& value) { return encoding[value]; } template void decode(std::vector const& v, OutputIterator iter); private: class Node; Node* tree; typedef std::map > encodemap; encodemap encoding; class NodeOrder; }; template struct Hufftree::Node { Frequency frequency; Node* leftChild; union { Node* rightChild; // if leftChild != 0 DataType* data; // if leftChild == 0 }; Node(Frequency f, DataType d): frequency(f), leftChild(0), data(new DataType(d)) {} Node(Node* left, Node* right): frequency(left->frequency + right->frequency), leftChild(left), rightChild(right) {} ~Node() { if (leftChild) { delete leftChild; delete rightChild; } else { delete data; } } void fill(std::map >& encoding, std::vector& prefix) { if (leftChild) { prefix.push_back(0); leftChild->fill(encoding, prefix); prefix.back() = 1; rightChild->fill(encoding, prefix); prefix.pop_back(); } else encoding[*data] = prefix; } }; template template Hufftree::Hufftree(InputIterator begin, InputIterator end): tree(0) { std::priority_queue, NodeOrder> pqueue; while (begin != end) { Node* dataNode = new Node(begin->second, begin->first); pqueue.push(dataNode); ++begin; } while (!pqueue.empty()) { Node* top = pqueue.top(); pqueue.pop(); if (pqueue.empty()) { tree = top; } else { Node* top2 = pqueue.top(); pqueue.pop(); pqueue.push(new Node(top, top2)); } } std::vector bitvec; tree->fill(encoding, bitvec); } template struct Hufftree::NodeOrder { bool operator()(Node* a, Node* b) { if (b->frequency < a->frequency) return true; if (a->frequency < b->frequency) return false; if (!a->leftChild && b->leftChild) return true; if (a->leftChild && !b->leftChild) return false; if (a->leftChild && b->leftChild) { if ((*this)(a->leftChild, b->leftChild)) return true; if ((*this)(b->leftChild, a->leftChild)) return false; return (*this)(a->rightChild, b->rightChild); } return *(a->data) < *(b->data); } }; template template std::vector Hufftree::encode(InputIterator begin, InputIterator end) { std::vector result; while (begin != end) { typename encodemap::iterator i = encoding.find(*begin); result.insert(result.end(), i->second.begin(), i->second.end()); ++begin; } return result; } template template void Hufftree::decode(std::vector const& v, OutputIterator iter) { Node* node = tree; for (std::vector::const_iterator i = v.begin(); i != v.end(); ++i) { node = *i? node->rightChild : node->leftChild; if (!node -> leftChild) { *iter++ = *(node->data); node = tree; } } }