DS二叉樹--赫夫曼樹的構建與編碼
阿新 • • 發佈:2018-12-17
題目描述 給定n個權值,根據這些權值構造huffman樹,並進行huffman編碼
參考課本演算法,注意陣列訪問是從位置1開始
要求:赫夫曼的構建中,預設左孩子權值不大於右孩子權值
輸入 第一行輸入t,表示有t個測試例項 第二行先輸入n,表示第1個例項有n個權值,接著輸入n個權值,權值全是小於1萬的正整數 依此類推
輸出 逐行輸出每個權值對應的編碼,格式如下:權值-編碼
即每行先輸出1個權值,再輸出一個短劃線,再輸出對應編碼,接著下一行輸入下一個權值和編碼。 以此類推樣例輸入
1 5 15 4 4 3 2
樣例輸出
15-1
4-010
4-011
3-001
2-000
思路
#include<iostream> #include<string> #include<cstring> using namespace std; const int maxW= 9999; class HuffNode{ public: int weight; int parent; int leftChild; int rightChild; }; class HuffMan{ private: void MakeTree(){ for(int i= lnum+ 1; i<= len; i++){ int s1, s2; SelectMin(i- 1, &s1, &s2); //cout<<s1<<s2<<"bbbbbbbbbbb"<<endl; //cout<<huffTree[s1].weight<<' '<<huffTree[s2].weight<<endl; huffTree[s1].parent= huffTree[s2].parent= i; huffTree[i].leftChild= s1; huffTree[i].rightChild= s2; huffTree[i].weight= huffTree[s1].weight+ huffTree[s2].weight; } } void SelectMin(int pos, int *s1, int *s2){ int w1, w2, i; w1= w2= maxW; *s1= *s2= 0; for(i= 1; i<= pos ; i++){ if(w1> huffTree[i].weight&&!huffTree[i].parent){ w2= w1; *s2= *s1; w1= huffTree[i].weight; *s1= i; } else if(w2> huffTree[i].weight&&!huffTree[i].parent){ w2= huffTree[i].weight; *s2= i; } } } public: int len; int lnum; HuffNode *huffTree; string *huffCode; void MakeTree(int n, int wt[]){ int i; lnum= n; len= 2*n- 1; huffTree = new HuffNode[2*n]; huffCode= new string[lnum+ 1]; for(i= 1; i<= n; i++) huffTree[i].weight= wt[i- 1]; for(i= 1; i<= len; i++){ if(i> n) huffTree[i].weight= 0; huffTree[i].parent= 0; huffTree[i].leftChild= 0; huffTree[i].rightChild= 0; } MakeTree(); } void Coding(){ char *cd; int i, c, f, start; cd= new char[lnum]; cd[lnum- 1]= '\0'; for(i= 1; i<= lnum; i++){ start= lnum- 1; for(c= i, f= huffTree[i].parent; f!= 0; c= f, f= huffTree[f].parent) if(huffTree[f].leftChild== c){ cd[--start]= '0'; //cout<<cd[start]; } else{ cd[--start]= '1'; // cout<<cd[start]; } //cout<<"aaaaaaaa"<<endl; huffCode[i].assign(&cd[start]); //cout<<huffCode[i]<<&cd[start]<<endl; } delete []cd; } void Destroy(){ len= 0; lnum= 0; delete []huffTree; delete []huffCode; } }; int main(){ int t, n,i,j; int wt[800]; HuffMan myHuff; cin>>t; for(i= 0; i< t; i++){ cin>>n; for(j= 0; j< n; j++) cin>>wt[j]; myHuff.MakeTree(n, wt); myHuff.Coding(); for(j= 1; j<= n; j++){ cout<<myHuff.huffTree[j].weight<<'-'; cout<<myHuff.huffCode[j]<<endl; } myHuff.Destroy(); } return 0; }