Huffman编码压缩~

实在没动力写下去了,先存个档。 读档时间未定~ 一两天, 一两个月 , 或者一辈子。

Huffman.cpp

  1 #include "stdafx.h"
  2 #include "Huffman.h"
  3 #include <iostream>
  4 #include <math.h>
  5 #include <queue>
  6 #include <stack>
  7 using namespace std;
  8 
  9 
 10 HuffmanTree::HuffmanTree():m_root(NULL), m_nNode(0), m_nTotalNode(0)
 11 {
 12     memset(m_code, 0, sizeof(HuffmanCode) * 256);    
 13 }
 14 
 15 HuffmanTree::~HuffmanTree()
 16 {
 17     if(m_root != NULL)
 18         delete m_root;
 19     DestoryTree(m_root);
 20 }
 21 
 22 Huffman_node* HuffmanTree::CreateNode(unsigned char value, int weight)
 23 {
 24     Huffman_node* p = new Huffman_node;
 25     p->weight = weight;
 26     p->value = value;
 27     p->leftchild = NULL;
 28     p->rightchild = NULL;
 29     p->parent = NULL;
 30     
 31     return p;
 32 }
 33 
 34 int HuffmanTree::DestoryTree(Huffman_node* root)
 35 {
 36     queue<Huffman_node*> qNode;
 37     Huffman_node* temp;
 38 
 39     qNode.push(root);
 40     while(!qNode.empty())
 41     {
 42         temp = qNode.front(); 
 43         qNode.pop();
 44         if(temp->leftchild != NULL)
 45             qNode.push(temp->leftchild);
 46         if(temp->rightchild != NULL)
 47             qNode.push(temp->rightchild);
 48         delete temp;
 49     }
 50 
 51     return true;
 52 }
 53 
 54 Huffman_node* HuffmanTree::MergeNode(Huffman_node* first, Huffman_node* sencond)
 55 {
 56     Huffman_node* root = CreateNode(0, first->weight + sencond->weight);
 57     root->leftchild = first;
 58     root->rightchild = sencond;
 59     first->parent = root;
 60     sencond->parent = root;
 61 
 62     return root;
 63 }
 64 
 65 Huffman_node* HuffmanTree::BuildHuffmanTree(void* buf, int len)
 66 {
 67     long                    Table[256] = {0};
 68     int                        count;
 69     Huffman_node*            minimal[2];
 70     Huffman_node*            temp;
 71     priority_queue<Huffman_node*>    nodelist;
 72 
 73     for(int i = 0; i < len; i++)
 74     {
 75         Table[((unsigned char*)buf)[i]] += 1;
 76     }
 77     
 78     for(int i = 0; i < 256; i++)
 79     {
 80         if(Table[i] != 0)
 81         {
 82             temp = CreateNode(i, Table[i]);
 83             nodelist.push(temp);
 84             m_leaves.push_back(temp);
 85         }
 86     }
 87     
 88     m_nNode = nodelist.size();
 89     m_nTotalNode = m_nNode * 2 - 1;
 90 
 91     Huffman_node* root;
 92     while(1)
 93     {
 94         //找到2个权值最小的节点
 95         minimal[0] = nodelist.top();
 96         nodelist.pop();
 97 
 98         minimal[1] = nodelist.top();
 99         nodelist.pop();
100 
101         root = MergeNode(minimal[0], minimal[1]);
102         if(nodelist.empty())
103             break;
104         nodelist.push(root);
105     }
106 
107     return root;
108 }
109 
110 void PrintTree(Huffman_node* root)
111 {
112     //if(root->leftchild == NULL)
113 }
114 
115 int HuffmanTree::IsLeftChild(Huffman_node* node)
116 {
117     if(node->parent == NULL)
118         return -1;
119     if(node->parent->leftchild == node)
120         return 1;
121     else
122         return 0;
123 }
124 
125 int HuffmanTree::CovertBits(vector<char> vecBits, void* code_buf)
126 {
127     int len = 0;
128     for(int i = 0; i < vecBits.size(); i += 8)
129     {
130         int num = 0;
131         for(int j = 0; j < 8; j++)
132         {
133             num += (vecBits[i+j] * (int)pow(2.0,7-j));    
134         }
135         ((unsigned char*)code_buf)[len++] = num;
136     }
137 
138     return len;
139 }
140 
141 
142 void HuffmanTree::GenerateCode(Huffman_node* root)
143 {
144     vector<Huffman_node *>::iterator iter;
145 
146     for(iter = m_leaves.begin(); iter != m_leaves.end(); iter++)
147     {
148         Huffman_node* temp = *iter;
149         char c = temp->value;
150 
151         while(temp != m_root)
152         {
153             if(IsLeftChild(temp))
154                 m_code[c].bit.push_back(0);
155             else
156                 m_code[c].bit.push_back(1);
157             temp = temp->parent;
158         }
159     }
160 }
161 
162 
163 int HuffmanTree::_Code(void* buf, int len, void* code_buf)
164 {
165     vector<char> bits;
166 
167     code_buf = new unsigned char[len + 1];
168     m_root = BuildHuffmanTree(buf, len);
169     
170     //生成Huffman编码,编码是反向的,使用的时候逆向输出.
171     GenerateCode(m_root);
172 
173     for(int i = 0; i< len; i++)
174     {
175         unsigned char c = ((unsigned char *)buf)[i];
176         bits.insert(bits.end(), m_code[c].bit.rbegin(), m_code[c].bit.rend());
177     }
178 
179     int rest = bits.size() % 8;
180     if(rest)
181     {
182         for(int i = 0; i < (8-rest); i++)
183             bits.push_back(0);
184     }
185 
186     int code_len = CovertBits(bits, code_buf);
187 
188     return code_len;
189 }
190 
191 
192 int HuffmanTree::_Decode(void* buf, int len, void* decode_buf)
193 {
194     return 0;
195 }

Huffman.h

#include<vector>
using namespace std;

struct Huffman_node
{
	unsigned char value;
	int weight;
	Huffman_node* parent;
	Huffman_node* leftchild;
	Huffman_node* rightchild;

public:
	Huffman_node operator=(Huffman_node &x)
	{
		value		= x.value;
		weight		= x.weight;
		parent		= x.parent;
		leftchild	= x.leftchild;
		rightchild	= x.rightchild;
		
		return *this;
	}

	friend bool operator<(Huffman_node& first, Huffman_node& second)
	{
		return first.weight < second.value;
	}
};


struct HuffmanCode
{
	unsigned char value;
	vector<char> bit;
};

struct HuffmanCode_header
{
	unsigned int sign;		// 特征
	long compressSize;		// 压缩后大小
	long uncompressSize;	// 未压缩前大小
	unsigned int reserved;	// 保留
	unsigned int version;	// 版本
};

class HuffmanTree
{
private:
	Huffman_node* CreateNode(unsigned char value, int weight);
	int DestoryTree(Huffman_node* root);
	Huffman_node* MergeNode(Huffman_node* first, Huffman_node* sencond);
	Huffman_node* BuildHuffmanTree(void* buf, int len);
	void GenerateCode(Huffman_node* root);
	int IsLeftChild(Huffman_node* node);
	int CovertBits(vector<char> vecBits, void* code_buf);
	int _Code(void* buf, int len, void* code_buf);
	int _Decode(void* buf, int len, void* decode_buf);
	int LoadTreeFromFile();
	int SaveTreeToFile();

public:
	HuffmanTree();
	~HuffmanTree();
	

public:
	int m_nNode;
	int m_nTotalNode;
	Huffman_node* m_root;
	HuffmanCode m_code[256];
	vector<Huffman_node*> m_leaves;
};

  

原文地址:https://www.cnblogs.com/whoiskevin/p/2743240.html