堆应用---构造Huffman树(C++实现)
堆:
堆是STL中priority_queue的最高效的实现方式(关于priority_queue的用法:http://www.cnblogs.com/flyoung2008/articles/2136485.html)。
主要分为大根堆和小根堆。
是一棵完全二叉树。
堆的一次插入删除调整的时间复杂度都是logn。
Huffman树:
又称最优二叉树(带权路径中),带权路径长度最小的二叉树应是权值大的外节点离根结点最近的扩充二叉树(权值都在叶节点的二叉树)就是Huffman树。
算法:
将权值对应的节点全部放入一个小根堆中。
每次取出堆顶的两个节点,构造成一个新的节点,循环n-1次(n为节点数量)。
代码如下:
#include<iostream>
using namespace std;
template<class T>
struct TreeNode{
T data;//节点值
TreeNode<T> *left,*right,*parent;//左右孩子
TreeNode(){
left=NULL;
right=NULL;
parent=NULL;
}
TreeNode(T x,TreeNode<T> *l=NULL,TreeNode<T> *r=NULL,TreeNode<T> *p=NULL){
data=x;
left=l;
right=r;
parent=p;
}
bool operator <=(TreeNode<T> &r){
return data<=r.data;
}
bool operator <(TreeNode<T> &r){
return data<r.data;
}
bool operator >=(TreeNode<T> &r){
return data>=r.data;
}
bool operator >(TreeNode<T> &r){
return data>r.data;
}
}; template<class T>
class MinHeap{//最小堆
private:
T *heap;//堆数组
int maxSize;//堆最大容量
int currentSize;//当前容量
public:
MinHeap(int sz=){
maxSize=sz;
heap=new T[maxSize];
currentSize=;
}
~MinHeap(){
delete []heap;
}
T* getHeap(){
return heap;
}
void siftDown(int start,int m){//向下调整堆数组
int i=start;
int j=*i+;
T temp=heap[i];
while(j<=m){
if(j<m&&*heap[j]>*heap[j+]) j++;
if(*temp<=*heap[j]) break;
heap[i]=heap[j];
i=j;
j=*j+;
}
heap[i]=temp;
}
void siftUp(int start){//向上调整堆数组
int i=start;
int j=(i-)/;
T temp=heap[i];
while(i>){
if(*temp>=*heap[j]) break;
heap[i]=heap[j];
i=j;
j=(i-)/;
}
heap[i]=temp;
}
bool insert(const T& x){//插入元素
if(currentSize==maxSize) return false;
heap[currentSize]=x;
siftUp(currentSize);
currentSize++;
return true;
}
bool remove(T& x){//删除元素
if(!currentSize) return false;
x=heap[];
heap[]=heap[currentSize-];
currentSize--;
siftDown(,currentSize-);
return true;
}
}; template<class T>
class HuffmanTree{
public:
HuffmanTree(T w[],int n){//构造Huffman树
TreeNode<T> *temp,*first,*second,*parent;
MinHeap <TreeNode<T>* >hp;
for(int i=;i<n;i++){
temp=new TreeNode<T>(w[i]);
hp.insert(temp);
}
for(int i=;i<n-;i++){
first=new TreeNode<T>;
second=new TreeNode<T>;
hp.remove(first);
hp.remove(second);
parent=new TreeNode<T>;
merge(first,second,parent);
hp.insert(parent);
}
root=parent;
}
void merge(TreeNode<T> *first,TreeNode<T> *second,TreeNode<T>* parent){//选取两个最小带权节点合并
parent->left=first;
parent->right=second;
parent->data=first->data+second->data;
first->parent=parent;
second->parent=parent;
}
~HuffmanTree(){
destroy(root);
}
void destroy(TreeNode<T> *subTree){//递归删除以subTree为根的所有结点
if(subTree!=NULL){
destroy(subTree->left);
destroy(subTree->right);
delete subTree;
}
}
void preOrder(TreeNode<T> *subTree){//前序遍历
if(subTree!=NULL){
cout<<subTree->data<<" ";
preOrder(subTree->left);
preOrder(subTree->right);
}
}
TreeNode<T> *getRoot(){
return root;
}
private:
TreeNode<T> *root;
}; int main(){
int N,*w;
cout<<"输入元素总数:"<<endl;
cin>>N;
w=new int[N];
cout<<"输入这组整数:"<<endl;
for(int i=;i<N;i++){
cin>>w[i];
}
HuffmanTree<int> *ht=new HuffmanTree<int>(w,N);
TreeNode<int> *root=ht->getRoot();
cout<<"Huffman树前序遍历结果:"<<endl;
ht->preOrder(root);
delete ht,w;
return ;
}
堆应用---构造Huffman树(C++实现)的更多相关文章
- Huffman树的构造及编码与译码的实现
哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...
- 构造数列Huffman树总耗费_蓝桥杯
快排! /** 问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的 ...
- 数据结构-二叉树(6)哈夫曼树(Huffman树)/最优二叉树
树的路径长度是从树根到每一个结点的路径长度(经过的边数)之和. n个结点的一般二叉树,为完全二叉树时取最小路径长度PL=0+1+1+2+2+2+2+… 带权路径长度=根结点到任意结点的路径长度*该结点 ...
- HUFFMAN 树
在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么 ...
- 数据结构与算法(周鹏-未出版)-第六章 树-6.5 Huffman 树
6.5 Huffman 树 Huffman 树又称最优树,可以用来构造最优编码,用于信息传输.数据压缩等方面,是一类有着广泛应用的二叉树. 6.5.1 二叉编码树 在计算机系统中,符号数据在处理之前首 ...
- Huffman树与编码
带权路径最小的二叉树称为最优二叉树或Huffman(哈夫曼树). Huffman树的构造 将节点的权值存入数组中,由数组开始构造Huffman树.初始化指针数组,指针指向含有权值的孤立节点. b = ...
- Huffman树
结点定义: /* * Huffman树结点定义 */ struct Node { ElementType weight; // 结点的权值 struct Node *leftChild; // 结点的 ...
- [ACM] POJ 3253 Fence Repair (Huffman树思想,优先队列)
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25274 Accepted: 8131 Des ...
- Java蓝桥杯练习题——Huffman树
Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, -, pn-1},用这列数构造Huffman树的过程如下: 找到{pi}中 ...
随机推荐
- 卸载或安装Git出现Invalid drive错误的解决方案【简记】
前言:工作中由于公司的电脑(SSD+HDD)硬盘(HDD)突然坏了,只剩下一个系统盘(SSD).然后就是有个比较紧急的需求正在做,申请换的新硬盘不能立刻换上,因为工作的机器不在公司,操作远程机器工作, ...
- linux使用Nginx搭建静态资源服务器
最近公司需要做一个宣传片播放 视频有点大 好几百M 就想到使用Nginx来代理静态资源,在过程中出现了一些问题,比如端口没开.访问是403等,没有成功,后面慢慢查找问题,才发现大部分博客资料的都不全 ...
- Java基础系列--09_集合2
昨天介绍了集合的主要架构体系,今天主要的目的是学习集合的迭代器的遍历和List的特有功能. 迭代器: 概述:由于多种集合的数据结构不同,所以存储方式不同,取出方式也不同.但是他们都是有判断和获 ...
- Fiddler分享
链接:https://pan.baidu.com/s/162YmGb7-aUZ6xDf8eRfgpw 密码:j6er
- [十二省联考2019]D2T2春节十二响
嘟嘟嘟 这题真没想到这么简单-- 首先有60分大礼:\(O(n ^ 2logn)\)贪心.(我也不知道为啥就是对的) 然后又送15分链:维护两个堆,每次去堆顶的最大值. 这时候得到75分已经很开心了, ...
- Luogu1574 超级数
Luogu1574 超级数 \(n\) 次询问不超过 \(a_i\) 的最大反素数 \(n\leq10^5,\ a_i\leq10^{17}\) 数论 似乎重题 bzoj1053 [HAOI2007] ...
- html与ios交互方法 WebViewJavascriptBridge
WebViewJavascriptBridge 1.html调用ios的方法 <!DOCTYPE html> <html lang="en"> <he ...
- zoj 3605
链接 [https://vjudge.net/contest/293343#problem/F] 题意 就是有n碗,有一个宝石,知道开始宝石在那个碗下面 进行M次交换,但知道其中的k次,问你最可能在那 ...
- C# WinForm 技巧十: winfrom 全屏自适应屏幕分辨率
Rectangle rect = new Rectangle(); rect = Screen.GetWorkingArea(this); this.Width = rect.Width;//屏幕宽 ...
- NIO的初步入门
NIO java NIO简介 Java NIO 简介 是从java1.4版本开始引入的一个新的IO AP可以替代标准java IO API NIO与原来的IO有同样的作用和目的,但是使用方式完全不同 ...