堆:
  堆是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++实现)的更多相关文章

  1. Huffman树的构造及编码与译码的实现

    哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...

  2. 构造数列Huffman树总耗费_蓝桥杯

    快排! /** 问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的 ...

  3. 数据结构-二叉树(6)哈夫曼树(Huffman树)/最优二叉树

    树的路径长度是从树根到每一个结点的路径长度(经过的边数)之和. n个结点的一般二叉树,为完全二叉树时取最小路径长度PL=0+1+1+2+2+2+2+… 带权路径长度=根结点到任意结点的路径长度*该结点 ...

  4. HUFFMAN 树

    在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么 ...

  5. 数据结构与算法(周鹏-未出版)-第六章 树-6.5 Huffman 树

    6.5 Huffman 树 Huffman 树又称最优树,可以用来构造最优编码,用于信息传输.数据压缩等方面,是一类有着广泛应用的二叉树. 6.5.1 二叉编码树 在计算机系统中,符号数据在处理之前首 ...

  6. Huffman树与编码

    带权路径最小的二叉树称为最优二叉树或Huffman(哈夫曼树). Huffman树的构造 将节点的权值存入数组中,由数组开始构造Huffman树.初始化指针数组,指针指向含有权值的孤立节点. b = ...

  7. Huffman树

    结点定义: /* * Huffman树结点定义 */ struct Node { ElementType weight; // 结点的权值 struct Node *leftChild; // 结点的 ...

  8. [ACM] POJ 3253 Fence Repair (Huffman树思想,优先队列)

    Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25274   Accepted: 8131 Des ...

  9. Java蓝桥杯练习题——Huffman树

    Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, -, pn-1},用这列数构造Huffman树的过程如下: 找到{pi}中 ...

随机推荐

  1. Java Web Token - JWT

    JWT认证过程:https://www.codetd.com/article/3602378 JWT官方文档:https://jwt.io/introduction/

  2. 利用ELK分析Nginx日志生产实战(高清多图)

    本文以api.mingongge.com.cn域名为测试对象进行统计,日志为crm.mingongge.com.cn和risk.mingongge.com.cn请求之和(此二者域名不具生产换环境统计意 ...

  3. 什么是CAS机制?(转)

    围绕下面四个点展开叙述: 一:什么是CAS机制? 二:Java当中CAS的底层实现 三:CAS的ABA问题和解决方法 四:java8对CAS的优化 一:什么是CAS机制? 我们先看一段代码: 启动两个 ...

  4. linux 上 mysql 的使用

    1.登录mysql 第一次登录 没有密码 可以直接输入 mysql 有密码可以使用  mysql -u root -p  回车会提示需要输入密码  -u 用户名 -p 密码 这个mysql文件在/us ...

  5. Manifest merger failed : Attribute application@icon value=(@mipmap/ic_launcher) from AndroidManifest

    情况是这样子的,导入一个比较老的项目(两年前),它依赖于一个 Libraray,已经先导入了 library,现在导入项目的时候出了错 (1) Android Studio 目前提供将 SDK包成 . ...

  6. Python爬虫beautifulsoup4常用的解析方法总结

    摘要 如何用beautifulsoup4解析各种情况的网页 beautifulsoup4的使用 关于beautifulsoup4,官网已经讲的很详细了,我这里就把一些常用的解析方法做个总结,方便查阅. ...

  7. 一次单体测试的采坑--MatcherAssert.assertThat---org.hamcrest 和org.mockito

    单体测试测试环境ci上报这个错, 本地没问题. org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Descri ...

  8. jsp使用

    session.setAttribute("sessionName",Object); 用来设置session值的,sessionName是名称,object是你要保存的对象. s ...

  9. Laravel——安装Laravel-admin

    前言 环境 : WAMP | Windows 7 | PHP 7.0.4 | MySQL 5.7.11 | Apache 2.4.18 框架 : Laravel | Laravel-admin 文档 ...

  10. mac 下 clang++ 找不到头文件 stdlib.h

    因为要用 openmp库,用 clang++ 编译 c++程序,出现了如下报错: clang++ xx.cpp -o xx -fopenmp /usr/local/Cellar/llvm/7.0.0/ ...