Huffman树的构造及编码

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>

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值