二叉树应用-Huffman编码树(数据结构基础 第6周)
问题描述
分析
做了,在POJ上能AC,但是在coursera上一直提示Compile Error. 没找着问题,呃,,,
源码
#include<iostream>
using namespace std;template <class T>
class BinaryTreeNode
{
private:T element; //二叉树结点数据域BinaryTreeNode<T>* left; //二叉树结点指向左子树的指针BinaryTreeNode<T>* right; //二叉树结点指向左子树的指针
public:BinaryTreeNode();BinaryTreeNode(const T& ele); //给定数据的构造函数BinaryTreeNode(const T& ele,BinaryTreeNode* l, BinaryTreeNode* r);//给定数据的左右指针的构造函数T value() const; //返回当前结点的数据BinaryTreeNode<T>& operator= (BinaryTreeNode<T>& Node){this->element=Node.element; this->left=Node.left; this->right=Node.right;return *this;}; //重载赋值操作符bool operator> (BinaryTreeNode<T>& Node){return this->element>Node.element;}; //重载>操作符bool operator< (BinaryTreeNode<T>& Node){return this->element<Node.element;}; //重载<操作符BinaryTreeNode<T>* leftchild() const; //返回当前结点指向左子树的指针BinaryTreeNode<T>* rightchild() const; //返回当前结点指向右子树的指针void setLeftchild(BinaryTreeNode<T>*); //设置当前结点的左子树void setRightchild(BinaryTreeNode<T>*); //设置当前结点的右子树void setValue(const T& val); //设置当前结点的数据域bool isLeaf() const; //判定当前结点是否为叶结点,若是返回true
};template <class T>
class MinHeap
{
private:T* heapArray; //存放堆数据的数组int CurrentSize; //当前堆中的元素数目int MaxSize; //最大元素数目
public:MinHeap(const int n); //构造函数,参数n为堆的最大元素数目virtual ~MinHeap() {delete []heapArray;}; //析构函数bool isLeaf(int pos) const; //判断是否为叶节点int leftchild(int pos) const; //返回左孩子位置int rightchild(int pos) const; //返回右孩子位置int parent(int pos) const; //返回父结点位置bool Remove(int pos, T& node); //删除给定下标的元素, 返回其元素的值bool RemoveMin(T& node); //从堆顶删除最小值bool Insert(T& newNode); //向堆中插入新元素void SiftDown(int left); //从left开始向下筛选 void SiftUp(int position); //从position向上开始调整,使序列成为堆
};template <class T>
class HuffmanTree
{
private:BinaryTreeNode<T>* root; //Huffman树的树根BinaryTreeNode<T>* nodeArray; //用于保存树的每一个结点void MergeTree(BinaryTreeNode<T> &ht1,BinaryTreeNode<T> &ht2, BinaryTreeNode<T>* parent); //把ht1和ht2为根的Huffman子树合并成一棵以parent为根的二叉树int wep; //带权外部路径长度
public:HuffmanTree(T weight[],int n); //构造Huffman树,weight是存储权值的数组,n是数组长度 ~HuffmanTree(); //析构函数void traverseNode(BinaryTreeNode<T>* node, int length);int weightedExternalPath();
};int main() {int n;cin >> n;int weight[100]={0};for(int i=0; i<n; i++) {cin >> weight[i];}HuffmanTree<int> ht(weight, n);cout << ht.weightedExternalPath() << endl;return 0;
}/***************************BinaryTreeNode***************************************/
template<class T>
BinaryTreeNode<T>::BinaryTreeNode()
{left=right=NULL;
}template<class T>
BinaryTreeNode<T>::BinaryTreeNode(const T& ele) //给定数据的构造函数
{element=ele;left=right=NULL;
}template<class T>
BinaryTreeNode<T>::BinaryTreeNode(const T& ele,BinaryTreeNode* l, BinaryTreeNode* r)//给定数据的左右指针的构造函数
{element=ele;left=l;right=r;
}template<class T>
T BinaryTreeNode<T>::value() const
{return element;
}template<class T>
BinaryTreeNode<T>* BinaryTreeNode<T>::leftchild() const
{return left; //返回当前结点指向左子树的指针
}template<class T>
BinaryTreeNode<T>* BinaryTreeNode<T>::rightchild() const
{return right; //返回当前结点指向右子树的指针
} template<class T>
void BinaryTreeNode<T>::setLeftchild(BinaryTreeNode<T>* subroot)//设置当前结点的左子树
{left=subroot;
}template<class T>
void BinaryTreeNode<T>::setRightchild(BinaryTreeNode<T>* subroot)//设置当前结点的右子树
{right=subroot;
}template<class T>
void BinaryTreeNode<T>::setValue(const T& val) //设置当前结点的数据域
{element = val;
} template<class T>
bool BinaryTreeNode<T>::isLeaf() const //判定当前结点是否为叶结点,若是返回true
{return (left == NULL) && (right == NULL);
}/**********************MinHeap实现***************************/
template<class T>
MinHeap<T>::MinHeap(const int n)
{if(n<=0)return;CurrentSize=0;MaxSize=n;heapArray=new T[MaxSize]; //创建堆空间
}template<class T>
bool MinHeap<T>::isLeaf(int pos) const
{return (pos>=CurrentSize/2)&&(pos<CurrentSize);
}template<class T>
int MinHeap<T>::leftchild(int pos) const
{return 2*pos+1; //返回左孩子位置
}template<class T>
int MinHeap<T>::rightchild(int pos) const
{return 2*pos+2; //返回右孩子位置
}template<class T>
int MinHeap<T>::parent(int pos) const // 返回父节点位置
{return (pos-1)/2;
}template<class T>
void MinHeap<T>::SiftDown(int left)
{int i=left; //标识父结点int j=2*i+1; //标识关键值较小的子结点 T temp=heapArray[i]; //保存父结点//过筛while(j<CurrentSize){if((j<CurrentSize-1)&&(heapArray[j]>heapArray[j+1]))j++; //j指向右子结点if(temp>heapArray[j]){heapArray[i]=heapArray[j];i=j;j=2*j+1;}else break;}heapArray[i]=temp;
}template<class T>
void MinHeap<T>::SiftUp(int position)
{//从position向上开始调整,使序列成为堆int temppos=position;T temp=heapArray[temppos];while((temppos>0)&&(heapArray[parent(temppos)]>temp)){heapArray[temppos]=heapArray[parent(temppos)];temppos=parent(temppos);}heapArray[temppos]=temp;
}template<class T>
bool MinHeap<T>::Remove(int pos, T& node) // 删除给定下标的元素, 返回其元素的值
{if((pos<0)||(pos>=CurrentSize))return false;T temp=heapArray[pos];heapArray[pos]=heapArray[--CurrentSize]; //用最后的元素代替被删除的元素if (pos>0 && (heapArray[parent(pos)] > heapArray[pos]))SiftUp(pos); //上升筛else SiftDown(pos); //向下筛 node=temp;return true;
}template<class T>
bool MinHeap<T>::RemoveMin(T& node)
{if(CurrentSize==0){return false;}else{node = heapArray[0];heapArray[0]=heapArray[--CurrentSize]; //用最后的元素代替被删除的元素if (CurrentSize>1) {SiftDown(0);}return true;}
}template<class T>
bool MinHeap<T>::Insert(T& newNode)
{//向堆中插入一个结点if(CurrentSize>=MaxSize)return false;heapArray[CurrentSize]=newNode;SiftUp(CurrentSize);CurrentSize++;return true;
}/**********************Huffman实现***************************/
template <class T>
void HuffmanTree<T>::MergeTree(BinaryTreeNode<T> &ht1,BinaryTreeNode<T> &ht2, BinaryTreeNode<T>* parent)
{parent->setLeftchild(&ht1);parent->setRightchild(&ht2);parent->setValue(ht1.value()+ht2.value());
}template <class T>
HuffmanTree<T>::HuffmanTree(T weight[],int n):wep(0)
{nodeArray = new BinaryTreeNode<T>[2*n];MinHeap<BinaryTreeNode<T>> heap(n); //定义最小值堆 BinaryTreeNode<T> NodeList;for(int i=0;i<n;i++) //初始化{BinaryTreeNode<T> NodeList(weight[i]);heap.Insert(NodeList); //向堆中添加元素}int j=0;for(int i=0;i<n-1;i++) //通过n-1次合并建立Huffman树{BinaryTreeNode<T>* parent;parent=new BinaryTreeNode<T>;heap.RemoveMin(nodeArray[j++]); //选择权值最小的结点heap.RemoveMin(nodeArray[j++]); //选择权值次小的结点MergeTree(nodeArray[j-2],nodeArray[j-1],parent); //合并权值最小的两棵树heap.Insert(*parent); //把parent插入到堆中去root=parent; //建立根结点}
}template <class T>
HuffmanTree<T>::~HuffmanTree()
{delete [] nodeArray;
}template <class T>
void HuffmanTree<T>::traverseNode(BinaryTreeNode<T>* node, int length)
{if (node != NULL){if (node->leftchild()==NULL && node->rightchild()==NULL){wep += node->value()*length;}else {traverseNode(node->leftchild(), length+1); //访问左子树traverseNode(node->rightchild(), length+1); //访问右子树}}
}template <class T>
int HuffmanTree<T>::weightedExternalPath()
{traverseNode(root, 0);return wep;
}
二叉树应用-Huffman编码树(数据结构基础 第6周)相关推荐
- 二叉树应用-Huffman树类模板的实现(数据结构基础 第6周)
简单实现来了Huffman树,在找最小堆的过程中使用到了自己做的最小堆MinHeap. 之前写的关于树的类模板中一直存在一个问题:结点的内存管理太混乱,有些甚至存在临时变量里.这里直接在类内直接定义了 ...
- 数据结构二叉树之Huffman编码
二叉编码树以及Huffman编码 abstract: 在初学二叉树的时候,我们就提出了二叉树的一个基本应用:编码树.那么,就编码树我们究竟该如何实现呢?下面我们来探讨这个问题. 一.PFC编码以及 ...
- 二叉树--Huffman编码树--优先队列解法
超链接:Huffman编码树 总时间限制: 1000ms 内存限制: 65535kB 描述 构造一个具有n个外部节点的扩充二叉树,每个外部节点Ki有一个Wi对应,作为该外部节点的权.使得这个扩充 ...
- 【算法】Huffman编码(数据结构+算法)
1.描述 Huffman编码,将字符串利用C++编码输出该字符串的Huffman编码. Huffman树是一种特殊结构的二叉树,由Huffman树设计的二进制前缀编码,也称为Huffman编码在通信领 ...
- Huffman编码树 求WPL
描述 构造一个具有n个外部节点的扩充二叉树,每个外部节点Ki有一个Wi对应,作为该外部节点的权.使得这个扩充二叉树的叶节点带权外部路径长度总和最小: Min( W1 * L1 + W2 * L2 + ...
- huffman图像编码C语言,Huffman编码 数据结构 C语言
为解决广大童鞋的数据结构实验问题写下本文:(只做参考哦.) 实验要求: Huffman编码(二叉树) l实验目的:熟练掌握二叉树应用(Huffman编码)的基本算法实现. l实现功能:对输入的一串电文 ...
- 数据压缩实验三:用c语言实现Huffman编码和压缩效率分析
实验原理: 1.Huffman编码 Huffman编码是一种无失真的编码方式,是可变字长编码(VLC)的一种. Huffman编码基于信源的概率统计模型,它的基本思路是: 出现概率大的信源符号编长码, ...
- Huffman编码的C语言实现
实验原理 Huffman 编码 (1) Huffman Coding (霍夫曼编码)是一种无失真编码的编码方式,Huffman 编码是可变字长编码(VLC)的一种. (2)Huffman 编码基于信源 ...
- 奇妙的二叉树:Huffman的贡献
提起 Huffman 这个名字,程序员们至少会联想到二叉树和二进制编码.的确,我们总以 Huffman 编码来概括 D.A.Huffman 个人对计算机领域特别是数据压缩领域的杰出贡献.我们知道, ...
最新文章
- vscode 默认初始化_VSCode设置初始化模板
- 4kyu N linear
- Struts2文件上传的大小限制问题
- HTML在日期单元格添加小图片,如何给图片添加上文字、日期和自己名字的小水印呢?...
- Surface Book 3现身3DMark:10nm架构升级
- 热烈庆祝《Python可以这样学》在台湾发行繁体版
- Angualr 输入文本框监听enter回车键和esc键方法使用(附常用的键盘事件对应的键码)
- s5原生android 5.0,三星Galaxy S5/S4吃上原生安卓5.0棒棒糖
- java servlet配置_JavaWeb编程 Servlet的基本配置
- hash算法总结收集
- 汽车空调管路气密性检测
- 虚拟化、云计算、开放源代码及其他
- 抖音小程序Tiktok教程之 01 编写您第一个hello world程序(含视频教程)
- 爱存在用计算机怎么弹,qiukepingvf
- 如何使用物联网低代码平台进行设备调试?
- 如何快速制作一个H5单页面网站
- cad net 绘制带圆弧的多段线
- 26岁想转行做程序员是否可行?
- Groovy~Groovy的Map操作
- 韦根读卡电路c语言程序,RFID读卡模块电路图、PCB源文件 125K RFID读卡模块 - 下载 - 搜珍网...