霍夫曼编码实现

先把代码贴了,有时间再写思路。。

二叉树定义:

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
View Code

队列定义:

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
View Code

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
View Code

最小堆:

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
View Code

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
View Code

附上一篇比较好的介绍文档:

http://pan.baidu.com/s/1gdF3LGB

你可能感兴趣的:(编码)