哈弗曼树的实现

来源:互联网 发布:日本经济数据怎么找 编辑:程序博客网 时间:2024/05/20 20:56
#pragma once#include "targetver.h"#include <stdio.h>#include <iostream>#include <tchar.h>  //字符串宏,主要用来定义 ascii码和unicode 的标准化,使代码移植后,不需要修改相应的代码,重新编译即可使用#include <vector>#include <queue>#include <string>#include <iterator>using namespace std;template <typename T>struct TreeNode{TreeNode()         //树节点。{lchild = rchild = NULL;}int weight;               //权值T ch;                   //节点TreeNode *lchild;TreeNode *rchild;};//--------重载运算符函数--------友元函数----------------------//改变优先队列的默认优先级template <typename T>bool operator>(const TreeNode<T>& left,const TreeNode<T>& right){return (left.weight>right.weight);}template <typename T>class Huffman{public:Huffman();Huffman(vector<TreeNode<T>>&c);~Huffman();void print();template <typename T>friend bool operator>(const TreeNode<T> &left,const TreeNode<T> &right);protected:TreeNode<T> *huffmantree;void printHuffman(TreeNode<T>* root, string s);void distoryhuftree(TreeNode<T>* root);};template <typename T>Huffman<T>::Huffman()   //构造空的哈夫曼树{huffmantree = NULL;}template <typename T>Huffman<T>::Huffman(vector<TreeNode<T>>&c) //以一组节点构造哈夫曼树{size_t n = c.size();priority_queue < TreeNode<T>, vector< TreeNode<T> >, greater< TreeNode<T> > > q;//将所有节点插入优先队列中int i;for (i=0; i<static_cast<int>(n); i++){TreeNode<T> huffmanNode;huffmanNode.ch = c[i].ch;huffmanNode.weight = c[i].weight;huffmanNode.lchild = huffmanNode.rchild = NULL;q.push(huffmanNode);}for (i=0; i<static_cast<int>(n-1); i++){TreeNode<T>* tempNode = new TreeNode<T>;TreeNode<T>* xNode = new TreeNode<T>;TreeNode<T>* yNode = new TreeNode<T>;xNode->weight = q.top().weight;     //xNode指向队列中优先级最高的元素xNode->ch = q.top().ch;xNode->lchild = q.top().lchild;xNode->rchild = q.top().rchild;tempNode->lchild = xNode;q.pop();yNode->weight = q.top().weight;     //xNode指向队列中优先级最高的元素yNode->ch = q.top().ch;yNode->lchild = q.top().lchild;yNode->rchild = q.top().rchild;tempNode->rchild = yNode;q.pop();tempNode->weight = xNode->weight + yNode->weight;q.push(*tempNode);}huffmantree = new TreeNode<T>;*huffmantree = q.top();}template <typename T>Huffman<T>::~Huffman(){distoryhuftree(huffmantree);}template <typename T>void Huffman<T>::distoryhuftree(TreeNode<T>* root){if (root != NULL){distoryhuftree(root->lchild);distoryhuftree(root->rchild);delete root;}}template <typename T>void Huffman<T>::print()                //输出哈弗曼树接口{if(huffmantree)printHuffman(huffmantree,"");}template <typename T>void Huffman<T>::printHuffman(TreeNode<T>* root, string s)  //递归输出哈弗曼编码{if(root->lchild != NULL)printHuffman(root->lchild, s + "0");if(root->rchild != NULL)printHuffman(root->rchild, s + "1");if(root->lchild == NULL && root->rchild == NULL)cout<<"被编码对象"<<root->ch<<""<<"权值"<<root->weight<<""<<"编码为:"<<s<<endl;}

编写一个类模板,在类模板中重载了运算符,并把该函数声明为友元函数.如果在类体外定义该友元函数,则出现如下编译错误:
main.obj : error LNK2019: 无法解析的外部符号 "


原理:
1.模板函数的友元声明
模板在使用之前必须先声明。模板的使用由友元声明构成,不是由模板的声明构成。实际的模板声明必须在友元声明之前。
2.这是链接错误。

template <typename T>friend bool operator>(const TreeNode<T> &left,const TreeNode<T> &right); 

friend bool operator><type T>(const TreeNode<T> &left,const TreeNode<T> &right); 

用<>就是说> 后面跟上<>来表示该函数是一个实例,也可以直接声明该函数本身是一个模板,然后在外面定义。


#include "stdafx.h"#define  MSIZE 10int _tmain(int argc, _TCHAR* argv[]){char ch = 'y';while(ch == 'Y' || ch == 'y'){TreeNode<string> w[MSIZE];  //树节点的编号为字符串型的数据vector < TreeNode<string> > v;int len = 0;cout<<"请输入节点个数:";cin>>len;cout<<" 请输入len个节点的值和相应的权值。"<<endl;for (int i=0; i<len; i++){cin>>w[i].ch>>w[i].weight;}copy(w, w+len, back_inserter(v)); Huffman<string> huff(v);       //以容器中的节点  构造哈弗曼树huff.print();cout<<endl;cout<<"是否继续?y/n"<<endl;cin>>ch;}return 0;}


0 0
原创粉丝点击