二叉树应用-Huffman编码树(数据结构基础 第6周)
2016-07-10 20:52
375 查看
问题描述
分析
做了,在POJ上能AC,但是在coursera上一直提示Compile Error. 没找着问题,呃,,,
源码
分析
做了,在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; }
相关文章推荐
- MFT的0x10标准属性数据结构
- 数据结构之栈
- 半边数据结构
- ArrayListDemo
- 数据结构——线性表的实现
- 数据结构之拓扑排序
- 定制化高效使用Map的一些经验技巧
- 数据结构-单链表
- 数据结构学习笔记5——双链表的实现
- hashMap
- 数据结构-顺序表
- 链表的实现与原理
- UVA - 11995 I Can Guess the Data Structure! 猜猜数据结构(STL模拟)
- 复习(数据结构):动态数组:c++_常规写法
- 线段树【区庆亮】
- 二叉树应用-二叉搜索树(数据结构基础 第6周)
- 二叉树应用-二叉搜索树类模板的实现(数据结构基础 第6周)
- 算法导论 第三部分——基本数据结构——红黑树
- 数据结构-->二叉树的链式实现 ADT
- 可视化数据结构和算法,用图示来表示