檔案壓縮(哈夫曼樹實現)

2021-07-30 18:13:19 字數 4319 閱讀 3131

專案描述:

專案簡介:利用哈夫曼編碼的方式對檔案進行壓縮,並且對壓縮檔案可以解壓

開發環境:windows vs2013

專案概述:

1.壓縮

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

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

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

d.從哈夫曼樹中獲取哈夫曼編碼,然後再根據整個字元陣列來獲取出現了得字元的編碼

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

f.寫好配置檔案,統計每個字元及其出現次數,並以「字元+','+次數」的形式儲存到配置檔案中

2.解壓

a.讀取配置檔案,統計所有字元的個數

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

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

#pragma once

#includetemplatestruct less

};templatestruct greater

};templateclass heap

heap(t* array, size_t n) //建堆

for (int i = (_array.size() - 2) >> 1; i >= 0; --i)

}const t& top()const

void push(const t& x)

size_t size()

void pop()

bool empty()

void print()

cout << endl;

}protected:

void _adjustup(int child) //上調

else

}} void _adjustdown(int root) //下調

if (comfunc(_array[child], _array[parent]))

else

}}protected:

vector_array;

};void testheap()

; //heapheap(a, sizeof(a) / sizeof(a[0]));

//heap> heap(a, sizeof(a) / sizeof(a[0]));

heap> heap(a, sizeof(a) / sizeof(a[0]));

heap.print();

heap.push(25);

heap.print();

heap.pop();

heap.print();

}

#pragma once

#include"heap.h"

templatestruct huffmantreenode

};templateclass huffmantree

huffmantree(t* a, size_t n, const t& invalid = t()) //構建哈夫曼樹

};heapminheap;

for (size_t i = 0; i < n; ++i)

}while (minheap.size() > 1)

_root = minheap.top();

} node* getroot()

~huffmantree()

protected:

void _destory(node* root)

_destory(root->_left);

_destory(root->_right);

delete root;

} huffmantree(const huffmantree& tree);

huffmantree& operator=(const huffmantree& tree);

protected:

node* _root;

};void testhuffmantree()

bool operator<(const charinfo& info) const

charinfo operator+(const charinfo& info)

bool operator!=(const charinfo& info)const };

struct countinfo

;class filecompress

} void compress(const char* filename)

//構建huffman tree

charinfo invalid;

invalid._count = 0;

huffmantreetree(_info, 256, invalid);

//生成huffman code

gethuffmancode(tree.getroot());

//壓縮

//寫配置檔案

for (size_t i = 0; i < 256; ++i)

}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)

if (pos == 8) //滿8位寫進檔案中

}ch = fgetc(fout);

} if (pos)

fclose(fin);

fclose(fout);

} void gethuffmancode(huffmantreenode* root) //huffman編碼

if (root->_left == null && root->_right == null)

else

cur = parent;

parent = cur->_parent;

}reverse(code.begin(), code.end());

} gethuffmancode(root->_left);

gethuffmancode(root->_right);

} //解壓

void uncompress(const char* filename)

_info[(unsigned char)info._ch]._ch = info._ch;

_info[(unsigned char)info._ch]._count = info._count;

} //重建huffman樹

charinfo invalid;

invalid._count = 0;

huffmantreetree(_info, 256, invalid);

huffmantreenode* root = tree.getroot();

huffmantreenode* cur = root;

longtype count = root->_w._count;

int value = fgetc(fout);

if (value == eof) //只有一種字元

}} else

else

if (cur->_left == null && cur->_right == null)

}--pos;

}value = fgetc(fout);

}} fclose(fout);

fclose(fin);

}protected:

charinfo _info[256]; //所有字元資訊

};void testfilecompress()

int array[10] = ;huffmantreet(array, 10);}

#include #include #include using namespace std;

#include"heap.h"

#include"huffmantree.h"

#include"filecompress.h"

int main()

檔案壓縮(哈夫曼樹)

以字串 aaaabbbccd 為例實現檔案壓縮。1 統計各字元出現個數 a 4 b 3 c 2 d 1 2 利用各字元出現的次數作為權值構建huffman樹 哈夫曼樹又稱為最優二叉樹,是加權路徑長度最短的二叉樹。構建規則 每次在給定資料中挑選出兩個權值最小的數,分別作為左右孩子節點,構建乙個父節點將...

哈夫曼樹和哈夫曼編碼(檔案壓縮)

哈夫曼樹 huffman tree 帶權路徑長度 wpl 設二叉樹有n個葉子結點,每個葉子結點帶有權值wk,從根節點到每個葉子結點的長度為lk,則每個葉子結點帶權路徑長度之和就是 wk lk 求和 最優二叉樹或哈夫曼樹 wpl最小的二叉樹 哈夫曼樹的構造 每次把權值最小的兩棵二叉樹合併 1 huff...

檔案壓縮(哈夫曼壓縮)

檔案壓縮總結 哈夫曼壓縮 在學習哈弗曼壓縮之前,還是首先來了解什麼是哈夫曼樹,哈夫曼編碼。1.哈夫曼樹是一種最優二叉樹,它的帶權路徑長度達到最小。樹的帶權路徑長度為所有葉子結點帶權路徑長度之和。而結點的帶權路徑長度是結點的路徑長度乘以結點的權值。2.哈夫曼編碼是依據字元出現概率來構造異字頭的平均長度...