Huffman树的基本操作

来源:互联网 发布:Affinity photo mac 编辑:程序博客网 时间:2024/05/18 03:14
#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 << " ";elsecout << "该节点无左孩子" << " ";if (pnode->rchild != nullptr)cout << "其右节点值为:" << pnode->rchild->key << " ";elsecout << "该节点无右孩子" << " ";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(){}#endifint main(){Huffman<int> huffman;int a[] = { 10, 20, 30, 40 };huffman.create(a, 4);huffman.print();system("pause");return 0;}

原创粉丝点击