Node.h:
<span style="font-size:12px;">#include <iostream>
#include <string>
using namespace std;
//结点结构体定义
struct Node
{
double weight; //权值
char ch; //外结点名
string code; //编码
Node* lchild,*rchild,*parent;
Node(double _weight=0,char _ch='*',string _code="") //构造函数
:weight(_weight),ch(_ch),code(_code),lchild(NULL),rchild(NULL),parent(NULL){}
//运算符重载
bool operator<(Node &N){return weight<N.weight;}
bool operator<=(Node &N){return weight<=N.weight;}
bool operator>(Node &N){return weight>N.weight;}
bool operator>=(Node &N){return weight>=N.weight;}
};</span>
Huffman.h:
<span style="font-size:12px;">#include <iostream>
#include "Node.h"
using namespace std;
class HuffmanTree
{
private:
Node *root; //根结点
void destroy(Node *subtree); //删除树
void PreOrder(Node *subtree); //前序遍历
void InOrder(Node *subtree); //中序遍历
void LevelOrder(Node *subtree); //按层遍历
void PostOrder(Node *subtree); //后序遍历
void HuffmanCode(Node *&subtree); //对已创建好的Huffman树进行编码
public:
HuffmanTree(int A[],char B[],int n); //构造函数
~HuffmanTree(){destroy(root);} //析构函数
void PreOrder(){cout<<"前序遍历: ";PreOrder(root);cout<<endl;}
void InOrder(){cout<<"中序遍历: ";InOrder(root);cout<<endl;}
void PostOrder(){cout<<"后序遍历:";PostOrder(root);cout<<endl;}
void LevelOrder(){cout<<"按层遍历: ";LevelOrder(root);cout<<endl;}
void MergeTree(Node *&t1,Node *&t2,Node *&parent); //合并子树
void HuffmanCode(){cout<<"编码结果: "<<endl;HuffmanCode(root);cout<<endl;} //调用编码函数
};
</span>
MinHeap.h:
<span style="font-size:12px;">//最小堆,存放森林
#include "Node.h"
#define DefaultSize 50
template <class T>
class MinHeap
{
private:
T *heap;
int currentSize;
void SiftUp(int start);
void SiftDown(int start,int over);
public:
MinHeap():currentSize(0){ heap=new T[DefaultSize];}
~MinHeap(){currentSize=0;}
bool Insert(const T &x);
bool RemoveMin(T &x);
bool IsEmpty(){return (currentSize==0)?true:false;}
};
template <class T>
bool MinHeap<T>::Insert(const T &x)
{
heap[currentSize]=x;
SiftUp(currentSize);
currentSize++;
return true;
}
template <class T>
void MinHeap<T>::SiftUp(int start)
{
int j=start,i=(j-1)/2;
T t;
while(i>=0)
{
if(heap[j]>=heap[i]) break;
else
{
t=heap[j];
heap[j]=heap[i];
heap[i]=t;
j=i;i=(j-1)/2;
}
}
}
template <class T>
void MinHeap<T>::SiftDown(int start,int over)
{
T t;
int i=start,j=2*i+1;
while(j<=over)
{
if(j<over&&heap[j+1]<heap[j]) j++;
if(heap[j]>=heap[i]) break;
else
{
t=heap[j];
heap[j]=heap[i];
heap[i]=t;
i=j;j=2*i+1;
}
}
}
template <class T>
bool MinHeap<T>::RemoveMin(T &x)
{
if(!IsEmpty())
{
x=heap[0];
heap[0]=heap[currentSize-1];
currentSize--;
SiftDown(0,currentSize-1);
return true;
}
else return false;
}
</span>
Queue.h:
<span style="font-size:12px;">template <class T>
struct QNode
{
T data;
QNode *next;
QNode():next(NULL){}
QNode(T _data):data(_data),next(NULL){}
};
template <class T>
class Queue
{
private:
QNode<T> *front_,*rear;
public:
Queue():front_(NULL),rear(NULL){}
bool EnQueue(const T &x);
bool DeQueue(T &x);
T getFront();
T getRear();
int getSize();
bool IsEmpty();
};
template <class T>
bool Queue<T>::EnQueue(const T &x)
{
if(front_==NULL)
{
rear=front_=new QNode<T>(x);
return true;
}
else{
rear->next=new QNode<T>(x);
if(rear->next==NULL) return false;
rear=rear->next;
}
return true;
}
template <class T>
bool Queue<T>::DeQueue(T &x)
{
if(IsEmpty()) return false;
else
{
QNode<T> *p=front_;
x=front_->data;
front_=front_->next;
delete p;
return true;
}
}
template <class T>
T Queue<T>::getFront()
{
return front_->data;
}
template <class T>
T Queue<T>::getRear()
{
return rear->data;
}
template <class T>
int Queue<T>::getSize()
{
if(front_==NULL) return 0;
if(front_==rear&&front_!=NULL) return 1;
int n=2;
QNode<T> *current=front_;
while(current->next!=rear)
{
n++;
current=current->next;
}
return n;
}
template <class T>
bool Queue<T>::IsEmpty()
{
if(front_==NULL)
return true;
return false;
}</span>
Huffman.cpp:
<span style="font-size:12px;">#include <iostream>
#include <iomanip>
#include <string>
#include "Queue.h"
#include "MinHeap.h"
#include "Huffman.h"
using namespace std;
//构造函数
HuffmanTree::HuffmanTree(int A[],char B[],int n) //A为外结点权重,B为外结点名数组
{
int i;
MinHeap<Node > mh; //使用最小堆存放森林
Node *parent,*first,*second,*temp;
for(i=0;i<n;i++) //森林各棵树初始化
{
temp=new Node(A[i],B[i]);
mh.Insert(*temp); //插入到最小堆中
}
for(i=0;i<n-1;i++) //循环n-1趟,形成huffman树
{
first=new Node;
second=new Node;
parent=new Node;
mh.RemoveMin(*first); //选出根的权值最小的树
mh.RemoveMin(*second); //选出根的权值次小的树
MergeTree(first,second,parent); //合并 将first和second权值相加赋给parent结点
mh.Insert(*parent); //将合并后得到的根结点插入到最小堆中
}
root=parent; //将建成的Huffman树根结点赋给root
}
//合并,将两个树根结点相加赋给parent结点,链接根结点与子女
void HuffmanTree::MergeTree(Node *&t1,Node *&t2,Node *&parent)
{
parent->weight=t1->weight+t2->weight;
parent->lchild=t1;
parent->rchild=t2;
t1->parent=t2->parent=parent;
}
//删除以subtree为根结点的子树
void HuffmanTree::destroy(Node *subtree)
{
if(subtree!=NULL)
{
destroy(subtree->lchild);
destroy(subtree->rchild);
delete subtree;
}
}
//前序遍历
void HuffmanTree::PreOrder(Node *subtree)
{
if(subtree!=NULL)
{
cout<<left<<setw(4)<<subtree->weight;
PreOrder(subtree->lchild);
PreOrder(subtree->rchild);
}
}
//中序遍历
void HuffmanTree::InOrder(Node *subtree)
{
if(subtree!=NULL)
{
InOrder(subtree->lchild);
cout<<left<<setw(4)<<subtree->weight;
InOrder(subtree->rchild);
}
}
//后序遍历
void HuffmanTree::PostOrder(Node *subtree)
{
if(subtree!=NULL)
{
PostOrder(subtree->lchild);
PostOrder(subtree->rchild);
cout<<left<<setw(4)<<subtree->weight;
}
}
//按层遍历
void HuffmanTree::LevelOrder(Node *subtree)
{
Queue<Node*> q;
Node *temp;
q.EnQueue(subtree);
while(!q.IsEmpty())
{
q.DeQueue(temp);
cout<<left<<setw(4)<<temp->weight;
if(temp->lchild!=NULL) q.EnQueue(temp->lchild);
if(temp->rchild!=NULL) q.EnQueue(temp->rchild);
}
}
//将Huffman树进行编码
void HuffmanTree::HuffmanCode(Node *&subtree)
{
Queue<Node*> q;
Node *temp;
q.EnQueue(subtree);
while(!q.IsEmpty())
{
q.DeQueue(temp);
Node *l=temp->lchild,*r=temp->rchild;
if(l==NULL&&r==NULL) //左右子树都为空,到达外结点,输出外结点编码
{
cout<<left<<temp->ch<<" : "<<temp->code<<endl;
continue;
}
if(l!=NULL){l->code=temp->code+"0";q.EnQueue(l);} //左子树不为空,左子树根结点编码+0
if(r!=NULL){r->code=temp->code+"1";q.EnQueue(r);} //右子树不为空,右子树根结点编码+1
}
}</span>
main.cpp:
<span style="font-size:12px;">#include <iostream>
#include "Huffman.h"
#define Max 100
using namespace std;
int main()
{
int A[Max],n,i;
char B[Max];
cout<<"请输入要创建的霍夫曼树的外结点个数: ";
cin>>n;
cout<<"请输入每个结点名: ";
for(i=0;i<n;i++)
cin>>B[i];
cout<<"请输入每个结点权重: ";
for(i=0;i<n;i++)
cin>>A[i];
HuffmanTree h(A,B,n);
h.HuffmanCode();
cout<<"遍历创建的Huffman树:"<<endl;
h.LevelOrder();
h.PreOrder();
return 0;
}</span>