堆:
  堆是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. 【Python实战】模块和包导入详解(import)

    1.模块(module) 1.1 模块定义 通常模块为一个.py文件,其他可作为module的文件类型还有".pyo".".pyc".".pyd&qu ...

  2. 基本MVVM 和 ICommand用法举例(转)

    引言 在本贴中,我们将学习WPF Commands. Commands 可以很好地与 MVVM 模式 (Model- View-ViewModel)结合在一起.我们也将看到,视图(view)实际上是怎 ...

  3. RestTemplate 发送 get 请求使用误区 多个参数传值为null(转载)

    首先看一下官方文档是怎么描述的,传递多个值的情况(注意例子中用到的@pathParam,一般要用@queryParam) RestTemplate 实例 @Configuration public c ...

  4. Codeforces #541 (Div2) - D. Gourmet choice(拓扑排序+并查集)

    Problem   Codeforces #541 (Div2) - D. Gourmet choice Time Limit: 2000 mSec Problem Description Input ...

  5. 逆向-攻防世界-no-strings-attached

    看题目就知道查找不到关键字符串,为防止踩坑,strings命令查看,没有找到有用的字符串.IDA载入程序查找入口函数, main函数中有4个函数,经过分析判断authenticate()为关键函数,跟 ...

  6. Android布局理解

    参考菜鸟教程,原文请查看:https://www.runoob.com/w3cnote/android-tutorial-linearlayout.html 1.FrameLayout(帧布局) 帧布 ...

  7. JSP中常用的的EL表达式的汇总

    Jsp基础知识 jsp的组成 html静态页面(css.javascript) java代码 <% %> (_jspService方法中) 内置对象 out request 表达式 < ...

  8. MVC多张图片上传

    1. 在视图中要写 @using (Html.BeginForm("AddProductaction","Admin",FormMethod.Post, new ...

  9. 【刷题】【LeetCode】000-十大经典排序算法

    [刷题][LeetCode]总 用动画的形式呈现解LeetCode题目的思路 参考链接 000-十大经典排序算法

  10. mysql 8.0.X 创建新的数据库、用户并授权

    一.创建数据库 mysql> create database jira; Query OK, 0 rows affected (0.09 sec) 二.创建用户 mysql> create ...