Huffman Tree 的构建和Huffman Code的实现

编译环境

IDE:  codeblocks

Compiler: GNU GCC

 

/*************************************************************************** * 功 能:Huffman Tree 的构建和Huffman Code 的实现 * 描 述:从文件source.txt中读取权重,然后构建顺序存储结构的Huffman Tree,继而实现该Huffman Tree的编码 * 作 者:JarvisChu * 时 间:2011-04-25 ***************************************************************************/ #include <iostream> #include <fstream> #include <string> #include <sstream> #include <malloc.h> using namespace std; #define NODE_MAX_SIZE 7 /*文件source.txt内容如下 A 12 B 11 C 13 D 14 E 9 F 8 G 3 */ /*Huffman Tree节点*/ typedef struct{ string data;//标识 int weight;//权重 int parent;//父节点 int lchild;//左孩子 int rchild;//右孩子 }HTNode,HuffmanTree; /*保存从文件中读取的一行数据*/ typedef struct{ string data; int weight; }Node; /*从0~i中选取parent = -1 的最小的两个节点存储序号s1,s2*/ bool Select(HuffmanTree HT[], int bound, int &s1, int &s2){ //先找到两个parent = -1的节点赋值给s1 s2 int index = 0; while(HT[index].parent != -1 && index <=bound){//找第一个 index++; } s1 = index; index++; // cout<<"aaa:"<<HT[bound].parent<<endl; while(HT[index].parent != -1 && index <=bound){//找第二个 index++; } s2 = index; //cout<<"bbb:"<<bound<<s1<<s2<<endl; if(HT[s1].weight > HT[s2].weight){//确保s1是最小 s2 = s1; s1 = index; } index++; while(index<= bound){ if(HT[index].parent == -1){ // cout<<index<<" "<<HT[index].weight<<" "<<HT[s1].weight<<endl; if(HT[index].weight <HT[s1].weight){//出现新的最小值 s2 = s1; s1 = index; // cout<<"出现最小值"<<endl; } else if(HT[index].weight >= HT[s1].weight && HT[index].weight < HT[s2].weight){//出现了新的次小值 s2 = index; // cout<<"出现次小值"<<endl; } } index++; } return true; } /*构建HuffmanTree T*/ bool CreateHuffmanTree(Node NodeArray[], HuffmanTree HT[]){ for(int i=0;i<NODE_MAX_SIZE;i++){ HT[i].data =NodeArray[i].data; HT[i].weight = NodeArray[i].weight; HT[i].parent = -1; HT[i].lchild = -1; HT[i].rchild = -1; } for(int i=NODE_MAX_SIZE;i<2*NODE_MAX_SIZE-1;i++){ HT[i].data =""; HT[i].weight = 0; HT[i].parent = -1; HT[i].lchild = -1; HT[i].rchild = -1; } int s1; int s2; for(int i=NODE_MAX_SIZE;i<2*NODE_MAX_SIZE-1;i++){ Select(HT,i-1,s1,s2);//从0~i中选取parent = -1 的最小的两个节点存储序号s1,s2 HT[i].data = HT[s1].data+HT[s2].data; HT[i].weight = HT[s1].weight+HT[s2].weight; HT[i].parent = -1; HT[i].lchild = s1; HT[i].rchild = s2; HT[s1].parent = i; HT[s2].parent = i; // cout<<"构造节点"<<s1<<" "<<s2<<" "<<i<<" "<<HT[i].data<<endl; } return true; } /*为Huffman Tree HT,构造Huffman Code,存放在HCode中*/ bool HuffmanCode(HuffmanTree HT[], string HCode[]){ //从叶子到根逆向求每个节点的Huffman Code for(int i=0;i<NODE_MAX_SIZE;i++){//从0~NODE_MAX_SIZE -1 保存的就是叶子节点,即需要编码的数据(文件中读取的数据) int start = 0; int c; int f;//父节点位置 for(c = i,f = HT[c].parent;f != -1/*不是根节点*/;c = f,f = HT[f].parent/*向父节点追溯*/){ if(HT[f].lchild == c){//如果当前节点是其父节点的左孩子,编码写入0 HCode[i].insert(start++,1,'0'); // cout<<"写入0"<<endl; } else{//如果当前节点是其父节点的右孩子,编码写入1 HCode[i].insert(start++,1,'1'); // cout<<"写入1"<<endl; } } // cout<<"--> "<<HCode[i]<<endl; } return true; } /*显示树的顺序存储结构中的数据*/ void DisplayTree(HuffmanTree HT[]){ cout<<endl<<"****************** Huffman Tree 存储结构 ********************"<<endl; for(int i=0;i<2*NODE_MAX_SIZE-1;i++){ cout<<i<<": "<<HT[i].data<<", "<<HT[i].weight<<", "<<HT[i].parent<<", "<<HT[i].lchild<<", "<<HT[i].rchild<<";"<<endl; } } /*显示Huffman Code*/ void DisplayHuffmanCode(string codes[], HuffmanTree HT[]){ cout<<endl<<"********************* Huffman Code *************************"<<endl; for(int i=0;i<NODE_MAX_SIZE;i++){ cout<<HT[i].data<<" :"<<codes[i]<<endl; } } int main() { /*从文件中读取数据并保存*/ Node NodeArray[NODE_MAX_SIZE]; fstream fs("source.txt"); stringstream ss; string line,strWeight; int separate = 0; for(int i=0;i<NODE_MAX_SIZE;i++){ getline(fs,line);//读取一行数据 separate = line.find(' ');//将标识和权重分隔开 NodeArray[i].data = line.substr(0,separate); strWeight = line.substr(separate+1,line.length()-separate); ss<<strWeight;//string 转 int ss>>NodeArray[i].weight; ss.clear();//如果没有此条语句,则后续读入的权重均不正确 } fs.close(); /*构建HuffmanTree*/ HuffmanTree HT[2*NODE_MAX_SIZE-1]; CreateHuffmanTree(NodeArray,HT); /*显示数组的数据*/ DisplayTree(HT); /*Huffman编码*/ string HuffmanCodes[NODE_MAX_SIZE];//保存Huffman彪马 HuffmanCode(HT,HuffmanCodes); /*输出Huffman Code*/ DisplayHuffmanCode(HuffmanCodes,HT); return 0; }

你可能感兴趣的:(c,String,struct,tree,存储,ide)