#ifndef _HUFFMAN_ #define _HUFFMAN_ #include <deque> #include <algorithm> //哈夫曼:树的带权路径(WPL)最小的二叉树。用变长编码表进行编码,编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的 template<typename T> struct HuffmanNode { HuffmanNode(T k, HuffmanNode<T>* l = nullptr, HuffmanNode<T>* r = nullptr) :key(k), lchild(l), rchild(r) {}; ~HuffmanNode(); T key; HuffmanNode<T>* lchild; HuffmanNode<T>* rchild; }; template<typename T> class Huffman { public: Huffman(); ~Huffman(); void preOrder();//前序遍历 void inOrder();//中序遍历 void postOrder();//后序遍历 void print();//打印 void create(T a[], int size);//创建哈夫曼数 void destory();//销毁哈夫曼树 private: void preOrder(HuffmanNode<T>* pnode); void inOrder(HuffmanNode<T>* pnode); void postOrder(HuffmanNode<T>* pnode); void print(HuffmanNode<T>* pnode); void destory(HuffmanNode<T>* pnode); private: HuffmanNode<T>* root;//哈夫曼数根节点 //deque<HuffmanNode<int>*> forest;//森林(队列) }; /* 哈夫曼树的构造步骤: 假设有n个权值,则构造出的哈夫曼树有n个叶子节点.n个权值记为{w1,w2,w3...wn},哈夫曼树的构造过程为: 1;将w1,w2,w3...wn看成具有n棵树的森林,每棵树仅有一个节点。 2.从森林中,选取两棵根节点权值最小的树,两棵树分别作为左子树与右子树,构建一棵新树。新树的权值等于左右子树权值之和。 3.从森林中删除两棵权值最小的树,将构建完成后的新树加入森林中。 4.重复2、3步骤,直到森林只剩一棵树为止。这棵树便是哈夫曼树。*/ template<typename T> void Huffman<T>::create(T a[], int size) { deque<HuffmanNode<T>*> forest;//森林(队列) for (int i = 0; i < size; i++) { HuffmanNode<T>* ptr = new HuffmanNode<T> (a[i], nullptr, nullptr); forest.push_back(ptr); } for (int i = 0; i < size-1; i++) { sort(forest.begin(), forest.end(), [](HuffmanNode<T>* a, HuffmanNode<T>* b){return a->key < b->key; }); HuffmanNode<T>* newptr = new HuffmanNode<T> (forest[0]->key + forest[1]->key, forest[0], forest[1]); forest.push_back(newptr); forest.pop_front(); forest.pop_front(); } root = forest.front(); forest.clear(); } //遍历 template<typename T> void Huffman<T>::print() { return print(root); } template<typename T> void Huffman<T>::print(HuffmanNode<T>* pnode) { if (pnode != nullptr) { cout << "当前节点值为:" << pnode->key << " "; if (pnode->lchild != nullptr) cout << "其左节点值为:" << pnode->lchild->key << " "; else cout << "该节点无左孩子" << " "; if (pnode->rchild != nullptr) cout << "其右节点值为:" << pnode->rchild->key << " "; else cout << "该节点无右孩子" << " "; cout << endl; print(pnode->lchild); print(pnode->rchild); } } //前序遍历 template<typename T> void Huffman<T>::preOrder() { return preOrder(root); } template<typename T> void Huffman<T>::preOrder(HuffmanNode<T>* pnode) { if (pnode!=nullptr) { cout << pnode->key<<" "; preOrder(pnode->lchild); preOrder(pnode->rchild); } } //中序遍历 template<typename T> void Huffman<T>::inOrder() { return inOrder(root); } template<typename T> void Huffman<T>::inOrder(HuffmanNode<T>* pnode) { if (pnode != nullptr) { inOrder(pnode->lchild); cout << pnode->key << " "; inOrder(pnode->rchild); } } //后序遍历 template<typename T> void Huffman<T>::postOrder() { return postOrder(root); } template<typename T> void Huffman<T>::postOrder(HuffmanNode<T>* pnode) { if (pnode != nullptr) { postOrder(pnode->lchild); postOrder(pnode->rchild); cout << pnode->key << " "; } } //后序销毁哈夫曼树 template<typename T> void Huffman<T>::destory() { return destory(root); } template<typename T> void Huffman<T>::destory(HuffmanNode<T>* pnode) { if (pnode!=nullptr) { if (pnode->lchild != nullptr) destory(pnode->lchild); if (pnode->rchild != nullptr) destory(pnode->rchild); delete pnode; pnode = nullptr; } } template<typename T> Huffman<T>::Huffman() { } template<typename T> Huffman<T>::~Huffman() { } #endif int main() { Huffman<int> huffman; int a[] = { 10, 20, 30, 40 }; huffman.create(a, 4); huffman.print(); system("pause"); return 0; }
Huffman树的基本操作
猜你喜欢
转载自blog.csdn.net/cat1992/article/details/76063148
今日推荐
周排行