霍夫曼编码与解码c++实现

来源:互联网 发布:org.apache.tools.zip. 编辑:程序博客网 时间:2024/06/08 00:22

看程序员面试笔试宝典,里面的霍夫曼编码解码代码全程c语言,看到我一头雾水,花了半天时间用c++写出来的代码,与大家分享!

c++代码实现:

/*

霍夫曼编码
*/
#include "stdafx.h"
#include <vector>
#include <string>
using namespace std;
struct HuffNode{
    int weight;//权值
char ch;//字符
char code;//编码
    HuffNode* parent;
    HuffNode* left;
    HuffNode* right;
HuffNode(int weight, char ch) : weight(weight), ch(ch),  code(' '), left(NULL), right(NULL) {};
};
/*快速排序*/
void quicksort(vector<char>& signal, vector<int>& weight, int i, int j)
{
if(i>=j)
return;
int start=i;
int end=j;
int key=weight[i];
char ch=signal[i];
// int temp;
while(j>i)
{
while(j>i&&weight[j]>=key)
j--;
weight[i]=weight[j];
signal[i]=signal[j];
while(i<j&&weight[i]<=key)
i++;
weight[j]=weight[i];
signal[j]=signal[i];
}
weight[i]=key;
signal[i]=ch;
quicksort(signal, weight,start,i-1);
quicksort(signal, weight,j+1,end);
}
/*调整*/
void adjust(vector<HuffNode*>& v, int &flag, HuffNode* tmp)
{
int left=flag;
int right=v.size()-1;
while(left<=right)//找到插入位置
{
if(v[left]->weight<=tmp->weight)
left++;
if(v[right]->weight>tmp->weight)
right--;
}
v.insert(v.begin()+left,tmp);
}
/*构建霍夫曼树*/
HuffNode* HuffCoding(vector<char>signal, vector<int> weight)
{
vector<HuffNode*> v;
quicksort(signal, weight, 0, weight.size()-1);
for(int i=0; i<signal.size(); i++)
{
HuffNode* ele=new HuffNode(weight[i],signal[i]);
v.push_back(ele);
}
HuffNode* head;
int flag=0;
while(flag<v.size()-1){
HuffNode* h1;
HuffNode* h2;
if(v[flag]->ch==' ')//编码字符作为左孩子
{
h1=v[flag+1];
       h2=v[flag];
}
else
{
h1=v[flag];
       h2=v[flag+1];
}
   HuffNode* tmp=new HuffNode(h1->weight+h2->weight,' ');
   tmp->left=h1;
   tmp->right=h2;
   h1->parent=tmp;
   h1->code='0';
   h2->parent=tmp;
   h2->code='1';
flag+=2;
head=tmp;
adjust(v,flag,tmp);//调整
}
return head;
}
/*读取霍夫曼码*/
vector<string> readcode(HuffNode* head)
{
HuffNode* now=head;
vector<char> f;//存放字符
vector<string> result;//存放编码结果
string str;
while(now!=NULL)
{
if(now->ch!=' ')//最后一个右孩子
{
f.push_back(now->ch);
result.push_back(str);
}


if(now->left!=NULL)
{
f.push_back(now->left->ch);
result.push_back(str+now->left->code);
}
now=now->right;
if(now!=NULL)
   str=str+now->code;
}
return result;
}
/*霍夫曼解码*/
vector<char> encode(HuffNode* head, vector<string> code)
{
vector<char> result;
for(int i=0; i<code.size(); i++)
{
HuffNode* now=head;
string str=code[i];
for(int j=0; j<str.length(); j++)
{
if(str[j]=='0')
now=now->left;
else
now=now->right;
}
result.push_back(now->ch);
}
return result;
}
int main()
{
char ch[]={'a','b','c','d','e'};
int w[]={4,8,1,2,11};
vector<char> signal(ch,ch+5);
vector<int> weight(w,w+5);
HuffNode* head=HuffCoding(signal, weight);
vector<string> code=readcode(head);
vector<char> result=encode(head,code);
return 0;
}
0 0