亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++數據結構之文件壓縮(哈夫曼樹)實例詳解

2020-01-26 13:59:41
字體:
來源:轉載
供稿:網友

C++數據結構之文件壓縮(哈夫曼樹)實例詳解

概要:

項目簡介:利用哈夫曼編碼的方式對文件進行壓縮,并且對壓縮文件可以解壓

開發環境:windows vs2013

項目概述:

        1.壓縮

            a.讀取文件,將每個字符,該字符出現的次數和權值構成哈夫曼樹

            b.哈夫曼樹是利用小堆構成,字符出現次數少的節點指針存在堆頂,出現次數多的在堆底

            c.每次取堆頂的兩個數,再將兩個數相加進堆,直到堆被取完,這時哈夫曼樹也建成

            d.從哈夫曼樹中獲取哈夫曼編碼,然后再根據整個字符數組來獲取出現了得字符的編碼

            e.獲取編碼后每次湊滿8位就將編碼串寫入到壓縮文件(value處理編碼1與它即可,0只移動位)

             f.寫好配置文件,統計每個字符及其出現次數,并以“字符+','+次數”的形式保存到配置文件中

         2.解壓

             a.讀取配置文件,統計所有字符的個數

             b.構建哈夫曼樹,讀解壓縮文件,將所讀到的編碼字符的這個節點所所含的字符寫入到解壓縮文件中,知道將壓縮文件讀完

             c.壓縮解壓縮完全完成,進行小文件大文件的測試

實例代碼:

#pragma once #include<vector>  template<class T> struct Less {   bool operator()(const T& l, const T& r) const   {     return l < r;   } };  template<class T> struct Greater {   bool operator()(const T& l, const T& r) const   {     return l > r;   } };  template<class T, class Compare> class Heap { public:   Heap()   {}    Heap(T* array, size_t n)   //建堆   {     _array.reserve(n);      for (size_t i = 0; i < n; i++)     {       _array.push_back(array[i]);     }      for (int i = (_array.size() - 2) >> 1; i >= 0; --i)     {       _AdjustDown(i);     }   }    const T& Top()const   {     return _array[0];   }    void Push(const T& x)   {     _array.push_back(x);     _AdjustUp(_array.size() - 1);   }    size_t Size()   {     return _array.size();   }    void Pop()   {     assert(_array.size() > 0);     swap(_array[0], _array[_array.size() - 1]);     _array.pop_back();     _AdjustDown(0);   }    bool Empty()   {     return _array.size() == 0;   }    void Print()   {     for (size_t i = 0; i < _array.size(); ++i)     {       cout << _array[i] << " ";     }     cout << endl;   }  protected:   void _AdjustUp(int child)  //上調   {     Compare ComFunc;     int parent = (child - 1) >> 1;     while (child)     {       if (ComFunc(_array[child], _array[parent]))       {         swap(_array[child], _array[parent]);         child = parent;         parent = (child - 1) >> 1;       }       else       {         break;       }     }   }       void _AdjustDown(int root)   //下調   {     Compare ComFunc;     int parent = root;     int child = root * 2 + 1;     while (child < _array.size())     {       if (child + 1 < _array.size() && ComFunc(_array[child + 1], _array[child]))       {         ++child;       }        if (ComFunc(_array[child], _array[parent]))       {         swap(_array[child], _array[parent]);         parent = child;         child = parent * 2 + 1;       }       else       {         break;       }     }   }    protected:   vector<T> _array;   };     void TestHeap() {   int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 };   //Heap<int> heap(a, sizeof(a) / sizeof(a[0]));   //Heap<int, Less<int>> heap(a, sizeof(a) / sizeof(a[0]));   Heap<int, Greater<int>> heap(a, sizeof(a) / sizeof(a[0]));   heap.Print();   heap.Push(25);   heap.Print();   heap.Pop();   heap.Print(); } 
#pragma once #include"Heap.h"  template<class T> struct HuffmanTreeNode {   HuffmanTreeNode<T>* _left;   HuffmanTreeNode<T>* _right;   HuffmanTreeNode<T>* _parent;   T _w;       //權值     HuffmanTreeNode(const T& x)     :_w(x)     , _left(NULL)     , _right(NULL)     , _parent(NULL)   {}  };  template<class T> class HuffmanTree {   typedef HuffmanTreeNode<T> Node; public:   HuffmanTree()     :_root(NULL)   {}    HuffmanTree(T* a, size_t n, const T& invalid = T())  //構建哈夫曼樹   {     struct Compare     {       bool operator()(Node* l, Node* r) const       {         return l->_w < r->_w;       }     };      Heap<Node*, Compare> minHeap;     for (size_t i = 0; i < n; ++i)     {       if (a[i] != invalid)       {         minHeap.Push(new Node(a[i]));       }     }      while (minHeap.Size() > 1)     {       Node* left = minHeap.Top();       minHeap.Pop();       Node* right = minHeap.Top();       minHeap.Pop();       Node* parent = new Node(left->_w + right->_w);       parent->_left = left;       parent->_right = right;       left->_parent = parent;       right->_parent = parent;       minHeap.Push(parent);     }     _root = minHeap.Top();   }     Node* GetRoot()   {     return _root;   }    ~HuffmanTree()   {     _Destory(_root);   }      protected:   void _Destory(Node* root)   {     if (root == NULL)     {       return;     }      _Destory(root->_left);     _Destory(root->_right);     delete root;   }    HuffmanTree(const HuffmanTree<T>& tree);   HuffmanTree& operator=(const HuffmanTree<T>& tree);  protected:   Node* _root;  };   void TestHuffmanTree() {<pre code_snippet_id="2340790" snippet_file_name="blog_20170418_2_3778260" name="code" class="cpp">#pragma once  #include<iostream> using namespace std; #include<assert.h> #include"HuffmanTree.h"   typedef long long LongType; struct CharInfo    {   unsigned char _ch;     //字符   LongType _count;     //字符出現的次數   string _code;      //huffman編碼    CharInfo(LongType count = 0)     :_count(count)     , _ch(0)     , _code("")   {}     bool operator<(const CharInfo& info) const   {     return _count < info._count;   }    CharInfo operator+(const CharInfo& info)   {     return CharInfo(_count + info._count);   }    bool operator!=(const CharInfo& info)const   {     return _count != info._count;   } };   struct CountInfo {   unsigned char _ch;    //字符   LongType _count;     //字符出現的次數 };     class FileCompress { public:   FileCompress()   {     for (size_t i = 0; i < 256; ++i)     {       _info[i]._ch = i;     }   }    void Compress(const char* filename)   {     assert(filename);          //統計字符出現的次數,均已二進制方式讀寫     FILE* fout = fopen(filename, "rb");     assert(fout);     int ch = fgetc(fout);      string CompressFile = filename;     CompressFile += ".huffman";     FILE* fin = fopen(CompressFile.c_str(), "wb");     assert(fin);     CountInfo info;       while (ch != EOF)     {       _info[(unsigned char)ch]._count++;       ch = fgetc(fout);     }      //構建huffman tree     CharInfo invalid;     invalid._count = 0;     HuffmanTree<CharInfo> tree(_info, 256, invalid);      //生成huffman code     GetHuffmanCode(tree.GetRoot());      //壓縮     //寫配置文件     for (size_t i = 0; i < 256; ++i)     {       if (_info[i]._count)       {         info._ch = _info[i]._ch;         info._count = _info[i]._count;         fwrite(&info, sizeof(info), 1, fin);       }     }      info._count = -1;     fwrite(&info, sizeof(info), 1, fin);      fseek(fout, 0, SEEK_SET);   //返回到文件開始     ch = fgetc(fout);     char value = 0;     //二進制     int pos = 0;    //左移位數     while (ch != EOF)     {       string& code = _info[(unsigned char)ch]._code;       size_t i = 0;       for (i = 0; i < code.size(); ++i)       {         value <<= 1;         ++pos;         if (code[i] == '1')         {           value |= 1;         }         if (pos == 8)       //滿8位寫進文件中         {           fputc(value, fin);           value = 0;           pos = 0;         }       }       ch = fgetc(fout);     }     if (pos)     {       value <<= (8 - pos);       fputc(value, fin);     }     fclose(fin);     fclose(fout);   }    void GetHuffmanCode(HuffmanTreeNode<CharInfo>* root)    //huffman編碼   {     if (root == NULL)     {       return;     }      if (root->_left == NULL && root->_right == NULL)     {       HuffmanTreeNode<CharInfo> *parent, *cur;       cur = root;       parent = cur->_parent;       string& code = _info[(unsigned char)root->_w._ch]._code;       while (parent)       {         if (cur == parent->_left)         {           code += '0';         }         else         {           code += '1';         }         cur = parent;         parent = cur->_parent;       }       reverse(code.begin(), code.end());     }     GetHuffmanCode(root->_left);     GetHuffmanCode(root->_right);   }    //解壓   void UnCompress(const char* filename)   {     assert(filename);     string UnCompressFile = filename;     size_t index = UnCompressFile.rfind('.');     assert(index != string::npos);     UnCompressFile = UnCompressFile.substr(0, index);     UnCompressFile += ".unhuffman";     FILE* fout = fopen(filename, "rb");     assert(fout);     FILE* fin = fopen(UnCompressFile.c_str(), "wb");     assert(fin);     CountInfo info;     fread(&info, sizeof(CountInfo), 1, fout);      //讀配置信息     while (1)     {       fread(&info, sizeof(CountInfo), 1, fout);       if (info._count == -1)       {         break;       }       _info[(unsigned char)info._ch]._ch = info._ch;       _info[(unsigned char)info._ch]._count = info._count;     }      //重建huffman樹     CharInfo invalid;     invalid._count = 0;     HuffmanTree<CharInfo> tree(_info, 256, invalid);     HuffmanTreeNode<CharInfo>* root = tree.GetRoot();     HuffmanTreeNode<CharInfo>* cur = root;     LongType count = root->_w._count;     int value = fgetc(fout);      if (value == EOF)       //只有一種字符     {       if (info._ch != 0)       {         while (cur->_w._count--)         {           fputc(cur->_w._ch, fin);         }       }     }     else     {       while (value != EOF)       {         int pos = 7;         char test = 1;         while (pos >= 0)         {           if (value & (test << pos))           {             cur = cur->_right;           }           else           {             cur = cur->_left;           }           if (cur->_left == NULL && cur->_right == NULL)           {             fputc(cur->_w._ch, fin);             cur = root;             if (--count == 0)             {               break;             }           }           --pos;         }         value = fgetc(fout);       }     }      fclose(fout);     fclose(fin);   }  protected:   CharInfo _info[256];   //所有字符信息 };  void TestFileCompress() {   FileCompress fc;   //fc.Compress("實驗.doc");   //fc.UnCompress("實驗.doc.huffman");   //fc.Compress("qq.JPG");   //fc.UnCompress("qq.JPG.huffman");   //fc.Compress("www.MP3");   //fc.UnCompress("www.MP3.huffman");    fc.Compress("yppppp.txt");   fc.UnCompress("yppppp.txt.huffman"); }</pre><br> int array[10] = { 2, 4, 6, 9, 7, 8, 5, 0, 1, 3 };HuffmanTree<int> t(array, 10);} <pre></pre> <p></p> <pre></pre> <p></p> <p></p> <p></p> <pre code_snippet_id="2340790" snippet_file_name="blog_20170418_3_1128302" name="code" class="cpp">#include <iostream> #include <assert.h> #include <windows.h> using namespace std;  #include"Heap.h" #include"HuffmanTree.h" #include"FileCompress.h"  int main() {   //TestHeap();     TestHuffmanTree();   TestFileCompress();     system("pause");   return 0; }</pre><br> <br> <p></p> <p><br> </p> <p><br> </p> <link rel="stylesheet"  rel="external nofollow" > 

 以上就是哈夫曼樹的實例詳解,如有疑問請留言或者到本站社區交流,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕精品网| 欧美精品18videos性欧美| 久久久久久高潮国产精品视| 久久久久久久久久久亚洲| 91成人国产在线观看| 亚洲情综合五月天| 欧美激情第99页| 成人精品网站在线观看| 日韩国产中文字幕| 91久久久久久久久| 26uuu另类亚洲欧美日本老年| 亚洲精品一区中文字幕乱码| 亚洲欧美另类人妖| 欧美视频精品一区| 最近2019中文字幕一页二页| 91精品视频专区| 韩国日本不卡在线| 欧美成人精品三级在线观看| 日韩中文在线视频| 欧美精品18videos性欧| 久久久久久久久久国产| 日韩精品日韩在线观看| 九九热精品视频在线播放| 国产成人免费av| 国产精品日韩欧美综合| 国产精自产拍久久久久久蜜| 91久久国产精品| 欧美激情视频网站| 第一福利永久视频精品| 日韩成人中文字幕在线观看| 中文字幕亚洲综合久久筱田步美| 91黑丝高跟在线| 国产精品久久久久久久久久三级| 日韩一区二区福利| 神马久久桃色视频| 国产欧美一区二区三区久久人妖| 久久精品99国产精品酒店日本| 青青草原成人在线视频| 色综合天天狠天天透天天伊人| 欧美大片大片在线播放| 欧美理论片在线观看| 黑人欧美xxxx| 91影院在线免费观看视频| 日韩精品免费在线视频观看| 91精品国产自产在线观看永久| 久久99久久99精品免观看粉嫩| 日韩福利视频在线观看| 国产91成人video| 97精品视频在线| 成人久久久久久| 97人人做人人爱| 亚洲乱码国产乱码精品精天堂| 91精品久久久久久久久中文字幕| 亚洲午夜精品视频| 国产精品444| 欧美日韩国产在线| 久久久久久91| 中文字幕综合一区| 日本亚洲欧洲色α| 国产精品精品一区二区三区午夜版| 成人精品一区二区三区电影黑人| 亚洲一区二区三区在线视频| 国产精品成久久久久三级| 黄色一区二区在线| 欧美国产极速在线| 高清日韩电视剧大全免费播放在线观看| 久久精品中文字幕免费mv| 国产日韩视频在线观看| 欧美黑人xxx| 欧美裸体xxxx极品少妇| 国产精品一区二区三区成人| 欧美成人合集magnet| 色综久久综合桃花网| 日本中文字幕久久看| 亚洲欧美制服另类日韩| 欧美日韩免费区域视频在线观看| 亚洲人在线观看| 亚洲自拍偷拍色片视频| 久久在线视频在线| 97精品伊人久久久大香线蕉| 日韩欧美视频一区二区三区| 国产999精品久久久影片官网| 亚洲精品乱码久久久久久金桔影视| 久久精品一区中文字幕| 亚洲视频国产视频| 亚洲男人天堂九九视频| 国产精品日韩在线| 亚洲夜晚福利在线观看| 91久久精品国产91性色| 欧美激情xxxx性bbbb| 在线播放国产一区中文字幕剧情欧美| 日韩精品免费在线观看| 成人做爰www免费看视频网站| 欧美韩国理论所午夜片917电影| 97在线观看免费高清| 北条麻妃在线一区二区| 亚洲精品日韩丝袜精品| 日韩视频免费看| 国产亚洲欧洲高清一区| 成人国产在线激情| 亚洲午夜国产成人av电影男同| 欧美亚洲国产成人精品| 综合欧美国产视频二区| 国产97在线|日韩| www亚洲欧美| 欧美中文字幕精品| 国内精品久久久久久久久| 亚洲色图综合久久| 这里只有视频精品| 色噜噜狠狠狠综合曰曰曰88av| 欧美精品www在线观看| 成人妇女淫片aaaa视频| 国产一区欧美二区三区| 性欧美暴力猛交69hd| 日产精品99久久久久久| 亚洲欧美另类人妖| 欧美成人午夜免费视在线看片| 97欧美精品一区二区三区| 日韩欧美亚洲成人| 国产精品三级网站| 亚洲国产精品成人va在线观看| 欧美中在线观看| 国产精品久久久久久久久久| 中文字幕国内精品| 欧美大片在线看免费观看| 成人综合网网址| 欧美日韩性视频| 欧美成年人视频网站| 成人性教育视频在线观看| 91天堂在线观看| 欧美日韩国产在线播放| 亚洲女性裸体视频| 国产精品视频久久| 最近2019中文字幕大全第二页| 国产精品高清在线| 成人97在线观看视频| 疯狂做受xxxx高潮欧美日本| 欧美色播在线播放| 久久影视电视剧免费网站清宫辞电视| 一级做a爰片久久毛片美女图片| 欧美亚洲激情在线| 亚洲影影院av| 在线播放日韩精品| 国产精品网站大全| 日韩中文字幕视频| 国语自产精品视频在免费| 久久午夜a级毛片| 欧美日韩国产精品一区二区三区四区| 精品亚洲一区二区三区| 日本韩国在线不卡| 久久九九亚洲综合| 在线丨暗呦小u女国产精品| 国产精品国模在线| 成人激情视频在线观看| 亚洲免费视频观看| 欧美黄色性视频| 久久精品国产69国产精品亚洲| 深夜精品寂寞黄网站在线观看| 国产精品尤物福利片在线观看| 中文字幕日韩欧美在线| 国产成人久久久精品一区| 亚洲一区二区三区四区视频| 福利视频导航一区| 国产伊人精品在线|