堆应用---构造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}中 ...
随机推荐
- samba介绍和安装
samba基本介绍 为什么需要samba 早期网络文件数据在不同主机之间传输大都可以使用Ftp完成,不过ftp使用有个小小的问题,它不能让你之间修改主机上的文件.要想修改必须要通过下载——修改——上传 ...
- mysql下载安装及常见问题
1.下载MySql 官网下载地址:https://dev.mysql.com/downloads/mysql/ 2.安装 如果下载的是zip的,直接解压目录即可,我的解压目录时:C:\mysql\my ...
- 解释型语言VS编译型语言
前言 计算机不能直接理解除机器语言以外的语言,所以只有把程序员编写的程序翻译成机器语言,计算机才能够执行程序. 将其他语言翻译成机器语言的工具,被称之为:编译器. 编译器的翻译方式有两种:编译和解释. ...
- 多态练习题(通过UML建模语言来实现饲养员喂养动物)
项目需求如下图: package com.Summer_0428.cn; /** * @author Summer * 1.构建一个食物抽象类,Bone和Fish分别为其实现类,通过super传参. ...
- 爬虫基础(五)-----scrapy框架简介
---------------------------------------------------摆脱穷人思维 <五> :拓展自己的视野,适当做一些眼前''无用''的事情,防止进入只关 ...
- Git使用(积累一些常用的命令)
1. 取消某一次合并 git merge --abort 可以参考的教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248 ...
- Echarts学习之路2(基本配置项)
title:标题组件,包含主标题和副标题. title:{ text:"",//主标题 link:"",//主标题文本超链接 target:"&quo ...
- Django1-HTTP协议介绍
何为http协议(Hypertext Transfer Protocol,超文本传输协议)? 所谓协议,就是指双方遵循的规范.http协议,就是浏览器和服务器之间进行“沟通”的一种规范.我们在看空间, ...
- filebeat-6.4.3-windows-x86_64输出Kafka
配置filebeat.yml文件 filebeat.prospectors: - type: log encoding: utf- enabled: true paths: - e:\log.log ...
- codevs 2370 小机房的树(LCA)
过了这么长的时间终于开始看LCA了... 有一次训练题卡在LCA当时不会...拖了好久好久...其实现在还是不会... 只会tarjan... 传送门 板子题咯 tarjan的算法就是基于先序遍历的顺 ...