哈夫曼树的c++实现

来源:互联网 发布:海南网络小贷牌照 编辑:程序博客网 时间:2024/06/05 00:28

      huffman 树称为最优二叉树,用其来对字符编码是一种比较好的选择,huffman树的实现也比较简单,构造huffman树的思想就是每次从序列中取出权值最小的两个,然后构造出一个树,然再去构造,一直到只有一个根节点为止。根据这个“每次从中选出最小的两个值”,我们应该想到优先队列,优先队列可以迅速的从一堆数中找出极小值或者极大值,用优先队列的这个性质可以很简单的构造huffman树。

    当然,构造huffman树只是第一步,构造完成之和,我们需要开始编码,其实就是遍历一遍整棵huffman树,然后给每个叶子节点一个编码,可以用“往左走填0,往右走填1”的方法来编码。

  解码就是遍历,到叶子节点也就可以取到这个编码所对应的值了。


  下面是我很久以前写的一个实现,可以输入一篇文章,该程序会首先对每个出现的单词计数(频率),然后构造huffman编码等,同时你还可以输入编码以解码。

  


/*编号:004_13名字:_Huffman_Tree描述:Huffman树与应用类备注:本类仅对小写英文字符实现,对于不同需求,请自行修改代码*/class _Huffman_Tree{public://the character and num//_Character_Num[character-'a'].int _Character_Num[26];int _All_Character_Num;char _Element_Data;int _Cost_character;_Huffman_Tree* _Root_Pointer;_Huffman_Tree* _Left_child_pointer;_Huffman_Tree* _Right_child_pointer;struct _character_code{char value;string code;};Vector<_character_code> _Huffman_code;_Huffman_Tree(){memset(_Character_Num, 0, sizeof(_Character_Num));_All_Character_Num = 0;_Root_Pointer = NULL;}_Huffman_Tree(char _Value, int _Weight, _Huffman_Tree* left_child, _Huffman_Tree* right_child){_Element_Data = _Value;_Cost_character = _Weight;_Left_child_pointer = left_child;_Right_child_pointer = right_child;}//judge if this node is leaf nodebool leaf(){return _Left_child_pointer == NULL&&_Right_child_pointer == NULL;}//you need to offer a file that stored the txt//count numvoid _Count_character_nums(string filename){//open fileifstream _Open;_Open.open(filename);string _Line;while (getline(_Open, _Line)){for (int i = 0; i < _Line.length(); i++){if (_Character_Num[(size_t)(_Line[i] - 'a')] == 0){_All_Character_Num++;}_Character_Num[(size_t)(_Line[i] - 'a')]++;}}_Open.close();}//function pointerclass _small_big{public:bool operator()(_Huffman_Tree* pointer1, _Huffman_Tree* pointer2){return pointer1->_Cost_character > pointer2->_Cost_character;}};//build huffman tree//return the root pointer of this huffman tree_Huffman_Tree* _Create_Huffman_Tree(){priority_queue<_Huffman_Tree*, vector<_Huffman_Tree*>,_small_big > _My_queue;//first push these leaf node into queuefor (int i = 0; i <26; i++){if (_Character_Num[i] != 0){_Huffman_Tree* _append_pointer = new _Huffman_Tree((char)('a' + i),_Character_Num[i], NULL, NULL);_My_queue.push(_append_pointer);}}//create this huffman treewhile (_My_queue.size()>1){_Huffman_Tree* _min_pointer_1 = new _Huffman_Tree;_Huffman_Tree* _min_pointer_2 = new _Huffman_Tree;_min_pointer_1 = _My_queue.top();_My_queue.pop();_min_pointer_2 = _My_queue.top();_My_queue.pop();_Huffman_Tree* _Append_pointer = new _Huffman_Tree(NULL,_min_pointer_1->_Cost_character +_min_pointer_2->_Cost_character,_min_pointer_1, _min_pointer_2);_My_queue.push(_Append_pointer);}return _My_queue.top();}//Encode huffman code//return voidvoid _Encode_huffman(_Huffman_Tree* _root_pointer,string _huffman_code){if (_root_pointer->leaf()){//this pointer is leaf node,so create it_character_code _append_code;_append_code.value = _root_pointer->_Element_Data;_append_code.code = _huffman_code;_Huffman_code._Push_back(_append_code);return;}string _left_code = _huffman_code;string _right_code = _huffman_code;_left_code += '1';_right_code += '0';_Encode_huffman(_root_pointer->_Left_child_pointer, _left_code);_Encode_huffman(_root_pointer->_Right_child_pointer, _right_code);}//Decode,so you need to offer a filename//this file need including some huffman code//the fuction will decode these huffman code void _Decode_huffman(_Huffman_Tree* _root_pointer,string filename){ifstream _read_file_stream;_read_file_stream.open(filename);string _read_one_line;while (getline(_read_file_stream, _read_one_line)){_Huffman_Tree* _decode_pointer = new _Huffman_Tree;_decode_pointer = _root_pointer;for (int i = 0; i < _read_one_line.length(); i++){if (_decode_pointer->leaf()){//this node is leaf node,so decode itcout << _decode_pointer->_Element_Data << " ";//return this decode pointer back root pointer_decode_pointer = _root_pointer;}if (_read_one_line[i] == '1'){_decode_pointer = _decode_pointer->_Left_child_pointer;}if (_read_one_line[i] == '0'){_decode_pointer = _decode_pointer->_Right_child_pointer;}}}_read_file_stream.close();}};



0 0
原创粉丝点击