Huffmanツリーの構造と符号化
7647 ワード
Node.h:
Huffman.h:
MinHeap.h:
Queue.h:
Huffman.cpp:
main.cpp:
#include
#include
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;}
};
Huffman.h:
#include
#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<
MinHeap.h:
// ,
#include "Node.h"
#define DefaultSize 50
template
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
bool MinHeap::Insert(const T &x)
{
heap[currentSize]=x;
SiftUp(currentSize);
currentSize++;
return true;
}
template
void MinHeap::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
void MinHeap::SiftDown(int start,int over)
{
T t;
int i=start,j=2*i+1;
while(j<=over)
{
if(j=heap[i]) break;
else
{
t=heap[j];
heap[j]=heap[i];
heap[i]=t;
i=j;j=2*i+1;
}
}
}
template
bool MinHeap::RemoveMin(T &x)
{
if(!IsEmpty())
{
x=heap[0];
heap[0]=heap[currentSize-1];
currentSize--;
SiftDown(0,currentSize-1);
return true;
}
else return false;
}
Queue.h:
template
struct QNode
{
T data;
QNode *next;
QNode():next(NULL){}
QNode(T _data):data(_data),next(NULL){}
};
template
class Queue
{
private:
QNode *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
bool Queue::EnQueue(const T &x)
{
if(front_==NULL)
{
rear=front_=new QNode(x);
return true;
}
else{
rear->next=new QNode(x);
if(rear->next==NULL) return false;
rear=rear->next;
}
return true;
}
template
bool Queue::DeQueue(T &x)
{
if(IsEmpty()) return false;
else
{
QNode *p=front_;
x=front_->data;
front_=front_->next;
delete p;
return true;
}
}
template
T Queue::getFront()
{
return front_->data;
}
template
T Queue::getRear()
{
return rear->data;
}
template
int Queue::getSize()
{
if(front_==NULL) return 0;
if(front_==rear&&front_!=NULL) return 1;
int n=2;
QNode *current=front_;
while(current->next!=rear)
{
n++;
current=current->next;
}
return n;
}
template
bool Queue::IsEmpty()
{
if(front_==NULL)
return true;
return false;
}
Huffman.cpp:
#include
#include
#include
#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 mh; //
Node *parent,*first,*second,*temp;
for(i=0;iweight=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<weight;
PreOrder(subtree->lchild);
PreOrder(subtree->rchild);
}
}
//
void HuffmanTree::InOrder(Node *subtree)
{
if(subtree!=NULL)
{
InOrder(subtree->lchild);
cout<weight;
InOrder(subtree->rchild);
}
}
//
void HuffmanTree::PostOrder(Node *subtree)
{
if(subtree!=NULL)
{
PostOrder(subtree->lchild);
PostOrder(subtree->rchild);
cout<weight;
}
}
//
void HuffmanTree::LevelOrder(Node *subtree)
{
Queue q;
Node *temp;
q.EnQueue(subtree);
while(!q.IsEmpty())
{
q.DeQueue(temp);
cout<weight;
if(temp->lchild!=NULL) q.EnQueue(temp->lchild);
if(temp->rchild!=NULL) q.EnQueue(temp->rchild);
}
}
// Huffman
void HuffmanTree::HuffmanCode(Node *&subtree)
{
Queue 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<ch<code<code=temp->code+"0";q.EnQueue(l);} // , +0
if(r!=NULL){r->code=temp->code+"1";q.EnQueue(r);} // , +1
}
}
main.cpp:
#include
#include "Huffman.h"
#define Max 100
using namespace std;
int main()
{
int A[Max],n,i;
char B[Max];
cout<>n;
cout<>B[i];
cout<>A[i];
HuffmanTree h(A,B,n);
h.HuffmanCode();
cout<