哈夫曼树
来源:互联网 发布:福州seo推广 编辑:程序博客网 时间:2024/05/16 20:32
huffman树,又称最优二叉树,是加权路径长度最短的二叉树
[贪心算法]是指在问题求解时,总是做出当前看起来最好的选择,通俗的说贪心算法不是整体最优的选择,而是局部最优解
使用贪心算法构建Huffman树
构建哈夫曼树主要包括两部分:
1:建小堆
2:将加权路径长度最短,构建最短二叉树
一:建小堆:
#pragma once#include<vector>#include<assert.h>using namespace std;template<class T>class Less{public: bool operator()(const T&a, const T&b) { return a < b; }};template<class T>class Greater{public: bool operator()(const T&a, const T&b) { return a>b; }};//小堆:任意一个节点是它子树的最大节点template<class T, class Compare = Less<T>>class Heap{public: Heap() {} Heap(T*a, size_t n) { _a.reserve(n);//增容(可以直接拷贝数据) for (size_t i = 0; i < n; i++) { _a.push_back(a[i]); } //调整成堆 for (int j = (_a.size() - 2) / 2; j >= 0; --j) { //向下调整 _AjustDown(j); } } //插入 void Push(const T&x) { _a.push_back(x); //调整成堆 _AjustUp(_a.size() - 1); } //删除 void Pop() { assert(!_a.empty()); swap(_a[0], _a[_a.size() - 1]);//根节点和最后一个叶子节点交换 _a.pop_back(); _AjustDown(0); } const T& Top() { return _a[0]; } size_t Size() { return _a.size(); } bool Empty() { return _a.empty(); }protected: //插入算法,主要影响root路径,向上 void _AjustUp(int child) { assert(!_a.empty()); int parent = (child - 1) >> 1; Compare comFunc;//调用仿函数 while (child>0) { //如果孩子节点的值大于父节点的值 if (comFunc(_a[child], _a[parent])) { swap(_a[child], _a[parent]); child = parent; parent = (child - 1) >> 1; } else { break; } } }protected: //向下调整成堆 void _AjustDown(int root) { Compare comFuc; int parent = root; int child = root * 2 + 1;//左孩子 while (child < _a.size()) { //选较小的孩子 if (child + 1 < _a.size() && comFuc(_a[child + 1], _a[child])) { ++child; } //比较父亲与孩子的大小 if (comFuc(_a[child], _a[parent])) { swap(_a[child], _a[parent]); parent = child; child = parent * 2 + 1; } else { break; } } }protected: vector<T>_a;};void TestHeap(){ int a1[] = { 10, 16, 18, 12, 13, 15, 17, 14, 19 }; size_t len = sizeof(a1) / sizeof(a1[0]); Heap<int, Less<int>> h1(a1, len); h1.Top(); /*h1.Push(25); h1.Pop();*/ while (!h1.Empty()) { cout << h1.Top() << " "; h1.Pop(); } cout << endl;}
二:构建哈夫曼树:
构建哈夫曼树,是所有叶子节点带权路径之和.
建树的思路:
1:将所有节点看成独立的树,且左右子树都为空,
2:选择权值最小的两个节点,生成一个节点作为它们的父节点,父节点的权值等于它们的权值之和
3:将父节点放回重复步骤2直到这个序列中只剩下最后一个节点,此时哈夫曼树就建成了.
#pragma once#include"Heap.h"#include<assert.h>using namespace std;template<class T>struct HuffmanTresNode{ T _w;//权值 HuffmanTresNode<T> *_left; HuffmanTresNode<T> *_right; HuffmanTresNode<T> *_parent; HuffmanTresNode(const T&x = T()) :_w(x) , _left(NULL) , _right(NULL) , _parent(NULL) {}};template<class T>class HuffmanTree{ typedef HuffmanTresNode<T> Node;public: //缺省的构造函数 HuffmanTree() :_root(NULL) {} HuffmanTree(T*a, size_t n, const T& invalid = T())//创建huffmanTree { assert(a); //_root = CreatHuffmanTree(a, n, invalid); //比较权值 struct Compare { bool operator()(const Node*l, const Node*r) const { return l->_w < r->_w; } }; Heap<Node*, Compare> minHeap;//所有元素建小堆 for (size_t i = 0; i < n; ++i) { if (a[i] != invalid) { minHeap.Push(new Node(a[i])); } } Node*left = NULL; Node*right = NULL; while (minHeap.Size()>1) { left = minHeap.Top(); minHeap.Pop(); right = minHeap.Top(); minHeap.Pop(); Node*parent = new Node(left->_w + right->_w); parent->_left = left; parent->_right = right; left->_parent = parent; right->_parent = parent; minHeap.Push(parent); } _root = minHeap.Top(); } Node* GetHuffmanTree() { return _root; } ~HuffmanTree() { if (_root != NULL) _Destroy(_root); }protected: //释放空间9 void _Destroy(Node*node) { if (node == NULL) return; _Destroy(node->_left); _Destroy(node->_right); delete node; }protected: Node* _root;};void TestHuffmanTree(){ int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; HuffmanTree<int> t(a, 10);}
当然哈夫曼树的一个重要应用就是通过哈夫曼编码来实现文件压缩,关于文件压缩后面我们再来探讨.
阅读全文
0 0
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 让大象起舞:企业运营敏捷之道
- 信号屏蔽pending
- 2.管理者的分类与角色
- 使用MySQL Connector 6+ 版本需要注意的一些问题
- Sqlite3详细解读
- 哈夫曼树
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”-- 一个看似简单的复杂问题
- 使用github和jekyll搭建个人免费托管博客
- EXE和SYS通信MiniFilter基于事件方式
- 【Kotlin】一个有趣的商品数量加减交互控件(商详页或者购物车商品数量的加减)
- python2.7基于selenium的web自动化测试项目--框架设计
- 制作本地YUM源
- Android ping
- Socket通信——TCP、UDP区别总结、使用场景