• 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;
    };
    

      

  • 相关阅读:
    全排列
    【React Native开发】React Native控件之DrawerLayoutAndroid抽屉导航切换组件解说(13)
    google PLDA + 实现原理及源代码分析
    codeforces 204(Div.1 A) Little Elephant and Interval(贪心)
    关于系统运维监控的几点建议
    jquery插件jTemplates使用方法
    手动控制事务
    Android--数据库数据显示至屏幕
    Qt应用程序中设置字体
    读刘未鹏老大《你应当怎样学习C++(以及编程)》
  • 原文地址:https://www.cnblogs.com/whoiskevin/p/2743240.html
Copyright © 2020-2023  润新知