先把代码贴了,有时间再写思路。。
二叉树定义:
binaryTree.h
1 #ifndef BINARYTREE_H 2 #define BINARYTREE_H 3 #include <iostream> 4 #include "LinkedQueue.h" 5 6 template<class T> 7 class BinaryTree; 8 9 10 int count; 11 12 template<class T> 13 class BinaryTreeNode 14 { 15 friend class BinaryTree < T > ; 16 friend void Visit(BinaryTreeNode<T> *); 17 friend void InOrder(BinaryTreeNode<T> *); 18 friend void PreOrder(BinaryTreeNode<T> *); 19 friend void PostOrder(BinaryTreeNode<T> *); 20 friend void LevelOrder(BinaryTreeNode<T> *); 21 public: 22 //构造函数 23 BinaryTreeNode(){ LeftChild = RightChild = 0; } 24 BinaryTreeNode(const T& e){ data = e; LeftChild = RightChild = 0; } 25 BinaryTreeNode(const T& e, BinaryTreeNode *l, BinaryTreeNode *r) 26 { 27 data = e; 28 LeftChild = l; 29 RightChild = r; 30 } 31 32 BinaryTreeNode<T>* GetLeft()const{ return LeftChild; } 33 BinaryTreeNode<T>* GetRight()const{ return RightChild; } 34 T GetData()const{ return data; } 35 private: 36 T data; 37 BinaryTreeNode<T> *LeftChild;//左子树 38 BinaryTreeNode<T> *RightChild;//右子树 39 }; 40 41 template<class T> 42 void Visit(BinaryTreeNode<T> *t) 43 { 44 std::cout << t->data << " "; 45 } 46 47 template<class T> 48 void PreOrder(BinaryTreeNode<T> *t) 49 { 50 if (t) 51 { 52 Visit(t); 53 PreOrder(t->LeftChild); 54 PreOrder(t->RightChild); 55 } 56 } 57 58 template<class T> 59 void InOrder(BinaryTreeNode<T> *t) 60 { 61 if (t) 62 { 63 InOrder(t->LeftChild); 64 Visit(t); 65 InOrder(t->RightChild); 66 } 67 } 68 69 template<class T> 70 void PostOrder(BinaryTreeNode<T> *t) 71 { 72 if (t) 73 { 74 PostOrder(t->LeftChild); 75 PostOrder(t->RightChild); 76 Visit(t); 77 } 78 } 79 80 template<class T> 81 void LevelOrder(BinaryTreeNode<T> *t) 82 { 83 LinkedQueue<BinaryTreeNode<T>*> Q; 84 while (t) 85 { 86 Visit(t); 87 88 if (t->LeftChild) 89 { 90 Q.Add(t->LeftChild); 91 } 92 if (t->RightChild) 93 { 94 Q.Add(t->RightChild); 95 } 96 97 if (Q.IsEmpty()) 98 { 99 return; 100 } 101 Q.Delete(t); 102 103 } 104 } 105 106 107 template<class T> 108 class BinaryTree 109 { 110 public: 111 BinaryTree(){ 112 root = NULL; 113 } 114 115 //复制构造函数 116 BinaryTree(const BinaryTree<T> &t); 117 ~BinaryTree(){ };//Delete(); }; 118 bool IsEmpty() const{ return root == NULL }; 119 bool Root(T& x)const; 120 void MakeTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right); 121 void BreakTree(T& element, BinaryTree<T> &left, BinaryTree<T> &right); 122 void FreeTree(){ Delete(); }; 123 void PreOrder(void(*Visit)(BinaryTreeNode<T> *u))const 124 { 125 PreOrder(Visit, root); 126 } 127 void InOrder(void(*Visit)(BinaryTreeNode<T> *u))const 128 { 129 InOrder(Visit, root); 130 } 131 void PostOrder(void(*Visit)(BinaryTreeNode<T> *u))const 132 { 133 PostOrder(Visit, root); 134 } 135 136 BinaryTreeNode<T>* CopyTree(const BinaryTreeNode<T>* t);//复制树 137 138 void PrintTree()const; 139 void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u))const; 140 void PreOutput()const; 141 void InOutput()const; 142 void PostOutput()const; 143 void LevelOutput()const; 144 void Delete(); 145 int Height()const 146 { 147 return Height(root); 148 } 149 150 int Size(); 151 152 BinaryTreeNode<T>* GetRoot()const{ return root; } 153 private: 154 BinaryTreeNode<T> *root; 155 void PreOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t)const; 156 void InOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t)const; 157 void PostOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t)const; 158 int Height(BinaryTreeNode<T> *t)const; 159 160 161 static void output(BinaryTreeNode<T> *t) 162 { 163 std::cout << t->data << ' '; 164 } 165 166 static void freeNode(BinaryTreeNode<T> *t) 167 { 168 delete t; 169 t = NULL; 170 } 171 172 static void ctsize(BinaryTreeNode<T> *t) 173 { 174 ++count; 175 } 176 177 }; 178 179 template<class T> 180 void BinaryTree<T>::PrintTree()const 181 { 182 183 } 184 185 template<class T> 186 BinaryTreeNode<T>* BinaryTree<T>::CopyTree(const BinaryTreeNode<T>* t) 187 { 188 BinaryTreeNode<T>* Node = NULL; 189 if (t) 190 { 191 BinaryTreeNode<T>* lchild = CopyTree(t->LeftChild); 192 BinaryTreeNode<T>* rchild = CopyTree(t->RightChild); 193 Node = new BinaryTreeNode<T>(t->data, lchild, rchild); 194 } 195 196 return Node; 197 } 198 199 template<class T> 200 BinaryTree<T>::BinaryTree(const BinaryTree<T> &t) 201 { 202 root = CopyTree(t.root); 203 } 204 205 206 207 template<class T> 208 int BinaryTree<T>::Size() 209 { 210 count = 0; 211 PreOrder(ctsize); 212 return count; 213 } 214 215 template<class T> 216 int BinaryTree<T>::Height(BinaryTreeNode<T> *t)const 217 { 218 if (!t) 219 { 220 return 0; 221 } 222 223 int ll = Height(t->LeftChild); 224 int lr = Height(t->RightChild); 225 226 if (ll > lr) 227 { 228 return ++ll; 229 } 230 else 231 return ++lr; 232 } 233 234 template<class T> 235 bool BinaryTree<T>::Root(T& x) const 236 { 237 if (root) 238 { 239 x = root->data; 240 return true; 241 } 242 return false; 243 } 244 245 template<class T> 246 void BinaryTree<T>::MakeTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right) 247 { 248 if (&left == &right) 249 { 250 BinaryTree<T> newTree(right); 251 if (&left != this) 252 { 253 root = new BinaryTreeNode<T>(element, left.root, newTree.root); 254 } 255 else 256 { 257 BinaryTree<T> newTree2(left); 258 root = new BinaryTreeNode<T>(element, newTree2.root, newTree.root); 259 } 260 } 261 else if (&left == this) 262 { 263 BinaryTree<T> newTree(left); 264 root = new BinaryTreeNode<T>(element, newTree.root, right.root); 265 } 266 else if (this == &right) 267 { 268 BinaryTree<T> newTree(right); 269 root = new BinaryTreeNode<T>(element, left.root, newTree.root); 270 } 271 else 272 root = new BinaryTreeNode<T>(element, left.root, right.root); 273 274 left.root = right.root = NULL; 275 } 276 277 template<class T> 278 void BinaryTree<T>::BreakTree(T& element, BinaryTree<T> &left, BinaryTree<T> &right) 279 { 280 if (root == NULL) 281 { 282 std::cerr << "树为空,不能拆分" << std::endl; 283 return; 284 } 285 286 BinaryTree<T> newTree = *this; 287 element = newTree.root->data; 288 left.root = newTree.root->LeftChild; 289 right.root = newTree.root->RightChild; 290 291 delete root; 292 root = NULL; 293 } 294 295 template<class T> 296 void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t)const 297 { 298 if (t) 299 { 300 Visit(t); 301 cout << endl; 302 cout<<"leftChild is: " 303 PreOrder(Visit, t->LeftChild); 304 PreOrder(Visit, t->RightChild); 305 } 306 } 307 308 template<class T> 309 void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t)const 310 { 311 if (t) 312 { 313 InOrder(Visit, t->LeftChild); 314 Visit(t); 315 InOrder(Visit, t->RightChild); 316 } 317 } 318 319 template<class T> 320 void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t)const 321 { 322 if (t) 323 { 324 PostOrder(Visit, t->LeftChild); 325 PostOrder(Visit, t->RightChild); 326 Visit(t); 327 } 328 } 329 330 template<class T> 331 void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T> *u))const 332 { 333 LinkedQueue<BinaryTreeNode<T>* > Q; 334 BinaryTreeNode<T> *t = root; 335 while (t) 336 { 337 cout << "root is "; 338 Visit(t); 339 cout << endl; 340 341 if (t->LeftChild) 342 { 343 Q.Add(t->LeftChild); 344 cout << "Leftchild of " << t->data << " is:"; 345 Visit(t->LeftChild); 346 cout << endl; 347 } 348 else 349 { 350 cout << t->data << " have no leftchild" << endl; 351 } 352 if (t->RightChild) 353 { 354 Q.Add(t->RightChild); 355 cout << "Rightchild of " << t->data << " is:"; 356 Visit(t->RightChild); 357 cout << endl; 358 } 359 360 else 361 { 362 cout << t->data << " have no Rightchild" << endl; 363 } 364 365 if (Q.IsEmpty()) 366 { 367 return; 368 } 369 Q.Delete(t); 370 } 371 } 372 373 template<class T> 374 void BinaryTree<T>::PreOutput()const 375 { 376 PreOrder(output, root); 377 } 378 379 template<class T> 380 void BinaryTree<T>::InOutput()const 381 { 382 InOrder(output, root); 383 } 384 385 template<class T> 386 void BinaryTree<T>::PostOutput()const 387 { 388 PostOrder(output, root); 389 } 390 391 template<class T> 392 void BinaryTree<T>::LevelOutput()const 393 { 394 LevelOrder(output); 395 } 396 397 template<class T> 398 void BinaryTree<T>::Delete() 399 { 400 PostOrder(freeNode, root); 401 root = NULL; 402 } 403 #endif
队列定义:
LinkedQueue.h:
1 #ifndef LINKEDQUEUE_H 2 #define LINKEDQUEUE_H 3 #include <iostream> 4 #include <new> 5 #include "exceptionerror.h" 6 7 template<class T> 8 class LinkedQueue;//声明模板类 9 10 template<class T> 11 class Node 12 { 13 public: 14 friend class LinkedQueue < T > ;//声明为友元,因为需要访问Node的私有成员 15 friend std::ostream& operator<<(std::ostream& output, const LinkedQueue<T>& q); 16 private: 17 Node<T> *next; 18 T data; 19 }; 20 21 template<class T> 22 class LinkedQueue 23 { 24 public: 25 LinkedQueue():front(0),rear(0){} 26 ~LinkedQueue(); 27 friend std::ostream& operator<<(std::ostream& output,const LinkedQueue<T>& q) 28 { 29 if (q.IsEmpty()) 30 { 31 output << "empty queue" << std::endl; 32 } 33 else 34 { 35 Node<T>* p = q.front; 36 while (p) 37 { 38 output << p->data << " "; 39 p = p->next; 40 } 41 } 42 43 return output; 44 } 45 bool IsEmpty()const{ return front == 0; } 46 bool IsFull()const; 47 T First()const;//返回第一个元素 48 T Last()const;//返回最后一个元素 49 LinkedQueue<T>& Add(const T& x);//添加元素 50 LinkedQueue<T>& Delete(T& x);//删除元素 51 int Quantity()const;//返回元素个数 52 private: 53 Node<T> *front; 54 Node<T> *rear; 55 }; 56 57 template<class T> 58 LinkedQueue<T>::~LinkedQueue() 59 { 60 Node<T>* next; 61 while (front) 62 { 63 next = front->next; 64 delete front; 65 front = next; 66 } 67 } 68 69 template<class T> 70 bool LinkedQueue<T>::IsFull()const 71 { 72 Node<T>* p; 73 try 74 { 75 p = new Node<T>; 76 delete p; 77 return false; 78 } 79 catch (CMemoryException* e) 80 { 81 return true; 82 } 83 } 84 85 template<class T> 86 T LinkedQueue<T>::First()const 87 { 88 if (IsEmpty()) 89 { 90 throw OutofBounds(); 91 } 92 93 return front->data; 94 } 95 96 template<class T> 97 T LinkedQueue<T>::Last()const 98 { 99 if (IsEmpty()) 100 { 101 throw OutofBounds(); 102 } 103 104 return rear->data; 105 } 106 107 template<class T> 108 LinkedQueue<T>& LinkedQueue<T>::Add(const T& x) 109 { 110 Node<T> *p = new Node<T>; 111 p->data = x; 112 p->next = 0; 113 if (front) 114 { 115 rear->next = p; 116 } 117 else front = p; 118 119 rear = p; 120 return *this; 121 } 122 123 template<class T> 124 LinkedQueue<T>& LinkedQueue<T>::Delete(T& x) 125 { 126 if (IsEmpty()) 127 { 128 throw OutofBounds(); 129 } 130 x = front->data; 131 Node<T>* p = front;//为了释放front空间 132 front = front->next; 133 delete p; 134 135 return *this; 136 } 137 138 template<class T> 139 int LinkedQueue<T>::Quantity()const 140 { 141 if (IsEmpty()) 142 { 143 return 0; 144 } 145 int count = 0; 146 Node<T>* p = front; 147 while (p) 148 { 149 p=p->next; 150 count++; 151 } 152 153 return count; 154 } 155 #endif
exceptionerror.h:
1 #ifndef EXCEPTIONERROR_H 2 #define EXCEPTIONERROR_H 3 #include <iostream> 4 class OutofBounds 5 { 6 public: 7 OutofBounds() 8 { 9 std::cerr << "Out of Bounds" << std::endl; 10 //std::exit(1); 11 } 12 }; 13 14 class NoMem 15 { 16 public: 17 NoMem(){ 18 std::cerr << "No Memory" << std::endl; 19 //std::exit(1); 20 } 21 22 }; 23 #endif
最小堆:
MinHeap.h
1 #ifndef MinHeap_H 2 #define MinHeap_H 3 4 #include<iostream> 5 #include<algorithm> 6 #include "exceptionerror.h" 7 using namespace std; 8 9 template<typename T> 10 class MinHeap 11 { 12 13 public: 14 MinHeap(int MaxHeapSize = 10); 15 ~MinHeap() 16 { 17 if (heap!=NULL) 18 { 19 delete[] heap; 20 heap = NULL; 21 } 22 } 23 24 int Size() const{ return CurrentSize; } 25 T Min() 26 { 27 if (CurrentSize==0) 28 { 29 throw OutofBounds(); 30 } 31 32 return heap[1]; 33 } 34 35 MinHeap<T>& Insert(const T& x); 36 MinHeap<T>& DeleteMin(T& x); 37 void Initialize(T a[], int size, int ArraySize); 38 private: 39 int CurrentSize; 40 int MaxSize; 41 T* heap; 42 }; 43 44 45 46 template<typename T> 47 MinHeap<T>::MinHeap(int MaxHeapSize=10):MaxSize(MaxHeapSize),CurrentSize(0) 48 { 49 heap = new T[MaxSize + 1]; 50 } 51 52 template<typename T> 53 MinHeap<T>& MinHeap<T>::Insert(const T& x) 54 { 55 size_t index = ++CurrentSize; 56 while (index!=1&&x<heap[index/2]) 57 { 58 heap[index] = heap[index / 2]; 59 index = index / 2;//移向父节点 60 } 61 62 heap[index] = x; 63 64 return *this; 65 } 66 67 template<typename T> 68 MinHeap<T>& MinHeap<T>::DeleteMin(T& x) 69 { 70 if (CurrentSize==0) 71 { 72 throw OutofBounds(); 73 } 74 75 x = heap[1]; 76 if (CurrentSize==1) 77 { 78 --CurrentSize; 79 return *this; 80 } 81 T temp = heap[CurrentSize--]; 82 size_t index = 1; 83 size_t cindex = 2; 84 while(cindex<=CurrentSize) 85 { 86 if (cindex<CurrentSize&&heap[cindex]>heap[cindex+1]) 87 { 88 ++cindex; 89 } 90 91 if (temp<=heap[cindex]) 92 { 93 break; 94 } 95 96 heap[index] = heap[cindex];//move down 97 index = cindex; 98 cindex *= 2; 99 } 100 101 heap[index] = temp; 102 return *this; 103 } 104 105 template<typename T> 106 void MinHeap<T>::Initialize(T a[], int size, int ArraySize) 107 { 108 delete[] heap; 109 heap = new T[ArraySize + 1]; 110 MaxSize = ArraySize; 111 CurrentSize = size; 112 113 memcpy(heap+1, a, (CurrentSize)*sizeof(T)); 114 115 size_t cindex; 116 for (size_t index = CurrentSize / 2; index >= 1;--index) 117 { 118 T temp = heap[index]; 119 120 cindex = 2 * index; 121 while (cindex<=CurrentSize) 122 { 123 if (cindex<CurrentSize&&heap[cindex + 1]<heap[cindex]) 124 { 125 ++cindex; 126 } 127 128 if (temp<=heap[cindex]) 129 { 130 break; 131 } 132 133 heap[cindex/2] = heap[cindex]; 134 cindex *= 2; 135 } 136 137 heap[cindex / 2] = temp; 138 } 139 140 } 141 #endif
Huffman.h:
1 #ifndef HUFFMAN_H 2 #define HUFFMAN_H 3 #include<iostream> 4 #include<fstream> 5 #include<vector> 6 #include<string> 7 #include<stack> 8 #include<map> 9 #include<bitset> 10 #include<iterator> 11 #include "binaryTree.h" 12 #include "MinHeap.h" 13 14 using namespace std; 15 const int NUM_CHARS = 256; 16 17 18 struct HuffCode 19 { 20 unsigned int size; 21 bitset<16> b; 22 }; 23 24 void create_freq_array(size_t freqs[NUM_CHARS], const string& str); 25 void print_table(const map<char, HuffCode>& m_table); 26 void create_header(size_t freqs[NUM_CHARS], const map<char, HuffCode>& m_table, string header, unsigned int size); 27 BinaryTree<char>& HuffmanTree(size_t freqs[NUM_CHARS]); 28 size_t huffman_compress(vector<unsigned char>& output, const string& input); 29 map<char, HuffCode>& create_table( map<char, HuffCode>& m_table, size_t freqs[NUM_CHARS], BinaryTree<char>& x); 30 31 size_t compress(map<char, HuffCode>& m_table, unsigned char* compressed, const string& input); 32 void set_bit(unsigned char* bits, unsigned int pos, unsigned int state); 33 unsigned int get_bit(unsigned char* bits, unsigned int pos); 34 unsigned int get_bit(const bitset<16>& b, unsigned int pos); 35 unsigned int get_bit(unsigned char c, unsigned int pos); 36 void write_binary(vector<unsigned char>& input, const char* filename); 37 void read_binary(vector<unsigned char>& output, const char* filename); 38 size_t huffman_uncompress(const vector<unsigned char>& compressed, vector<unsigned char>& uncompressed); 39 void uncompress(const BinaryTree<char>& huff_tree, unsigned char* compressed, vector<unsigned char>& uncompress, size_t size); 40 41 42 class Huffman 43 { 44 friend BinaryTree<char>& HuffmanTree(size_t []); 45 friend bool operator<(const Huffman& lhs,const Huffman& rhs) 46 { 47 return lhs.weight < rhs.weight ? true : false; 48 } 49 friend bool operator<=(const Huffman& lhs, const Huffman& rhs) 50 { 51 return lhs.weight <= rhs.weight ? true : false; 52 } 53 54 public: 55 operator size_t()const { return weight; } 56 Huffman() :weight(0),tree(){}; 57 private: 58 BinaryTree<char> tree; 59 size_t weight; 60 }; 61 62 /************************************************************************/ 63 /*构建霍夫曼树: 64 1.建立只包含一个结点的树 65 2.选取树中权重最小的2棵合并,将合并后的树放入集合中 66 3.重复2,直到只有一棵树 67 */ 68 /************************************************************************/ 69 BinaryTree<char>& HuffmanTree(size_t freqs[NUM_CHARS]) 70 { 71 BinaryTree<char> z, zero; 72 73 int count = 0; 74 for (int i = 0; i < NUM_CHARS;++i) 75 { 76 if (freqs[i]) 77 { 78 ++count; 79 } 80 } 81 Huffman *w = new Huffman[count]; 82 83 //建立count棵单节点树 84 int index = 0; 85 for (int i = 0; i < NUM_CHARS;++i) 86 { 87 if (freqs[i]) 88 { 89 z.MakeTree(static_cast<char>(i), zero, zero); 90 w[index].weight = freqs[i]; 91 w[index].tree = z; 92 index++; 93 } 94 } 95 96 97 MinHeap<Huffman>H(1); 98 H.Initialize(w, count, count);//用w初始化最小堆 99 100 Huffman x, y; 101 102 for (int i = 1; i < count;++i) 103 { 104 //选取权重最小的2棵树 105 H.DeleteMin(x); 106 H.DeleteMin(y); 107 108 //合并这2棵树 109 z.MakeTree(0, x.tree, y.tree); 110 x.weight += y.weight; 111 x.tree = z; 112 113 //重新插入最小堆 114 H.Insert(x); 115 } 116 117 H.DeleteMin(x); 118 delete[] w; 119 120 return x.tree; 121 } 122 123 //获取字符编码表 124 map<char,HuffCode>& create_table(map<char,HuffCode>& m_table,size_t freqs[NUM_CHARS],BinaryTree<char>& x) 125 { 126 //vector<string> path(7); 127 vector<BinaryTreeNode<char>* >pPath;//遍历的路径 128 BinaryTreeNode<char>* t = x.GetRoot(); 129 stack<BinaryTreeNode<char>*> s;//遍历所用栈 130 string temp;//二进制编码 131 BinaryTreeNode<char>* ttemp=NULL; 132 //前序遍历的循环模式 133 while (t||!s.empty()) 134 { 135 //遍历左子树 136 while (t!=NULL) 137 { 138 if (t->GetLeft()==NULL&&t->GetRight()==NULL) 139 { 140 m_table[t->GetData()].size=temp.size(); 141 m_table[t->GetData()].b = bitset<16>(temp); 142 } 143 s.push(t); 144 pPath.push_back(t); 145 146 t = t->GetLeft(); 147 //左子树存在,编码0 148 if (t!=NULL) 149 { 150 temp += '0'; 151 } 152 } 153 154 if (!s.empty()) 155 { 156 t = s.top(); 157 s.pop(); 158 159 ttemp = pPath.back(); 160 //路径回溯时将路径中与当前节点不同的节点删除 161 while(ttemp!=t) 162 { 163 temp.pop_back(); 164 pPath.pop_back(); 165 ttemp = pPath.back(); 166 } 167 168 t = t->GetRight(); 169 //右子树存在,编码1 170 if (t!=NULL) 171 { 172 temp += '1'; 173 } 174 } 175 176 } 177 178 //print_table(m_table); 179 return m_table; 180 } 181 182 183 void print_table(const map<char,HuffCode>& m_table) 184 { 185 map<char, HuffCode>::const_iterator cit = m_table.cbegin(); 186 for (; cit != m_table.cend(); ++cit) 187 { 188 cout << cit->first << " " ; 189 int size = cit->second.size; 190 for (int i = size - 1; i >= 0;--i) 191 { 192 cout << cit->second.b[i]; 193 } 194 cout << endl; 195 } 196 } 197 //统计字符频率 198 void create_freq_array(size_t freqs[NUM_CHARS], const string& str) 199 { 200 int i, maxfreq = 0; 201 202 memset(freqs, 0, sizeof(size_t)*NUM_CHARS); 203 204 size_t size = str.size(); 205 for (i = 0; i < size; ++i) 206 { 207 freqs[(unsigned char)str[i]]++; 208 209 if (freqs[(unsigned char)str[i]]>maxfreq) 210 { 211 maxfreq = freqs[(unsigned char)str[i]]; 212 } 213 } 214 215 //压缩字节频率 216 if (maxfreq>NUM_CHARS) 217 { 218 for (i = 0; i < NUM_CHARS;++i) 219 { 220 if (freqs[i]>0) 221 { 222 freqs[i] = static_cast<int>(freqs[i] * (double)NUM_CHARS / maxfreq + 0.5); 223 if (freqs[i]==0) 224 { 225 freqs[i] = 1; 226 } 227 } 228 } 229 } 230 } 231 232 233 void print_freqs(size_t freqs[NUM_CHARS]) 234 { 235 for (int i = 0; i < NUM_CHARS;++i) 236 { 237 if (freqs[i]) 238 { 239 cout << "char " << static_cast<char>(i) << " freq: " 240 << freqs[i] << endl; 241 } 242 } 243 } 244 245 void create_header(size_t freqs[NUM_CHARS], const map<char, HuffCode>& m_table, unsigned char* header, unsigned int size) 246 { 247 memcpy(header, &size, sizeof(int)); 248 249 250 for (size_t i = 0; i < NUM_CHARS;++i) 251 { 252 header[sizeof(int)+i] = static_cast<unsigned char>(freqs[i]); 253 } 254 255 } 256 257 size_t huffman_compress(vector<unsigned char>& compressed, const string& input) 258 { 259 size_t freqs[NUM_CHARS]; 260 create_freq_array(freqs, input); 261 262 print_freqs(freqs); 263 BinaryTree<char> huff_tree; 264 265 huff_tree = HuffmanTree(freqs); 266 map<char, HuffCode> m_table; 267 create_table(m_table, freqs, huff_tree); 268 print_table(m_table); 269 270 unsigned int headersize = sizeof(int) + NUM_CHARS; 271 unsigned char* header = new unsigned char[headersize]; 272 create_header(freqs, m_table, header, input.size()); 273 274 unsigned char* comstr = new unsigned char[input.size()]; 275 memset(comstr, 0, sizeof(char)*input.size()); 276 size_t codesize = compress(m_table, comstr, input); 277 278 cout << "compressed string size(in byte): " << codesize << endl; 279 280 for (size_t i = 0; i < 8 * codesize;++i) 281 { 282 cout << get_bit(comstr, i); 283 } 284 cout << endl; 285 286 for (size_t i = 0; i < headersize;++i) 287 { 288 compressed.push_back(header[i]); 289 } 290 for (size_t i = 0; i < codesize;++i) 291 { 292 compressed.push_back(comstr[i]); 293 } 294 295 296 delete[] header; 297 delete[] comstr; 298 huff_tree.FreeTree(); 299 return headersize+codesize; 300 } 301 302 // set the bit at position pos in the array bits to the value state 303 void set_bit(unsigned char* bits, unsigned int pos, unsigned int state) 304 { 305 unsigned char mask = 0x80; // = 128 dec = 10000000 bin 306 for (unsigned int i = 0; i < (pos % 8); i++) 307 mask = mask >> 1; // shift bitmask to right 308 309 if (state) 310 bits[pos / 8] = bits[pos / 8] | mask; 311 else 312 bits[pos / 8] = bits[pos / 8] & (~mask); 313 314 return; 315 } 316 317 318 // get the state of the bit at position pos in the array bits 319 unsigned int get_bit(const bitset<16>& b, unsigned int pos) 320 { 321 322 return b[pos]; 323 } 324 325 unsigned int get_bit(unsigned char* bits,unsigned int pos) 326 { 327 unsigned char mask = 0x80; // = 128 dec = 10000000 bin 328 /* 329 for (unsigned int i = 0; i < (pos % 8); i++) 330 mask = mask >> 1; // shift bitmask to right 331 */ 332 mask = mask >> (pos % 8); 333 334 return (((mask & bits[(int)(pos / 8)]) == mask) ? 1 : 0); 335 } 336 337 unsigned int get_bit(unsigned char c,unsigned int pos) 338 { 339 unsigned char mask = 0x80; 340 mask = mask >> (pos % 8); 341 342 return (mask&c) == mask ? 1 : 0; 343 } 344 size_t compress(map<char, HuffCode>& m_table, unsigned char* compressed, const string& input) 345 { 346 size_t size = input.size(); 347 char c; 348 size_t pos = 0; 349 for (size_t i = 0; i < size;++i) 350 { 351 c = input[i]; 352 for (size_t j = 0; j < m_table[c].size;++j) 353 { 354 set_bit(compressed, pos + j, get_bit(m_table[c].b, m_table[c].size-1-j)); 355 } 356 357 pos += m_table[c].size; 358 } 359 360 /* 361 for (size_t i = 0; i < pos; ++i) 362 { 363 cout << get_bit(compressed, i); 364 } 365 cout << get_bit(compressed, pos + 1); 366 cout << get_bit(compressed, pos + 1); 367 cout << endl; 368 */ 369 return (pos / 8 + 1); 370 } 371 372 void write_binary(vector<unsigned char>& input, const char* filename) 373 { 374 ofstream out(filename, ofstream::binary); 375 out.clear(); 376 377 if (out) 378 { 379 copy(input.begin(), input.end(), ostream_iterator<unsigned char>(out)); 380 out.close(); 381 } 382 383 } 384 385 void read_binary(vector<unsigned char>& output, const char* filename) 386 { 387 unsigned char c; 388 ifstream in("test.bin", ifstream::binary); 389 if (in) 390 { 391 while (!in.eof()) 392 { 393 c = in.get(); 394 output.push_back(c); 395 } 396 in.close(); 397 } 398 } 399 400 size_t huffman_uncompress(const vector<unsigned char>& compressed, vector<unsigned char>& uncompressed) 401 { 402 unsigned int freqs[NUM_CHARS]; 403 unsigned int headersize = sizeof(int) + NUM_CHARS; 404 size_t size = 0; 405 unsigned char* comp = new unsigned char[compressed.size()]; 406 for (size_t i = 0; i < compressed.size();++i) 407 { 408 comp[i] = compressed[i]; 409 } 410 memcpy(&size, comp, sizeof(int)); 411 412 cout << "size of compressed string(in byte): " << size << endl; 413 414 for (int i = 0; i < NUM_CHARS;++i) 415 { 416 freqs[i] = (unsigned int)comp[sizeof(int) + i]; 417 } 418 419 BinaryTree<char> huff_tree; 420 huff_tree = HuffmanTree(freqs); 421 uncompress(huff_tree, comp + headersize, uncompressed, size); 422 huff_tree.FreeTree(); 423 delete[]comp; 424 425 return size; 426 } 427 428 void uncompress(const BinaryTree<char>& huff_tree, unsigned char* compressed, vector<unsigned char>& uncompress, size_t size) 429 { 430 size_t length = 0; 431 unsigned int pos = 0; 432 unsigned int bit; 433 434 BinaryTreeNode<char>* pNode = NULL; 435 while (length<size) 436 { 437 pNode = huff_tree.GetRoot(); 438 while (pNode->GetLeft()!=NULL&&pNode->GetRight()!=NULL) 439 { 440 bit = get_bit(compressed, pos++); 441 if (bit) 442 { 443 pNode = pNode->GetRight(); 444 } 445 else 446 pNode = pNode->GetLeft(); 447 } 448 449 uncompress.push_back(pNode->GetData()); 450 ++length; 451 } 452 } 453 454 #endif
附上一篇比较好的介绍文档: