1 #include<iostream> 2 #include<stdlib.h> 3 #include<string.h> 4 #define INF 10000000 //定義INF爲無窮大 5 using namespace std; 6 struct Node{ 7 char data='\0'; //定義當前結點的字符,初始化爲'\0' 8 int value=0; //定義結點的權值,初始化爲 0 9 string code=""; //存儲哈夫曼編碼,初始化爲空字符串 10 Node *lchild,*rchild,*parents; //定義左右子結點、雙親結點 11 }; 12 Node * insert_huffman_tree(Node *root,Node *lchild,Node *rchild){ //哈夫曼樹的插入函數 13 root->lchild=lchild; 14 root->rchild=rchild; 15 return root; //返回根結點 16 } 17 void get_huffman_code(Node *root){ //獲取哈夫曼編碼函數 18 if(root->lchild==NULL&&root->rchild==NULL){ //說明是葉子結點 19 cout<<"字符 "<<root->data<<" 的哈夫曼編碼爲: "<<root->code<<endl; //輸出當前字符的哈夫曼編碼 20 return ; //結束遞歸 21 } 22 root->lchild->code=(root->code)+"0"; //左子結點爲 0 23 get_huffman_code(root->lchild); //遞歸左子樹 24 root->rchild->code=(root->code)+"1"; //右子結點爲 1 25 get_huffman_code(root->rchild); //遞歸右子樹 26 return ; //結束遞歸 27 } 28 int main(){ 29 Node *root; 30 cout<<"下一行輸入一串僅包含小寫字母的字符串:"<<endl; 31 char s[100]; //定義長度爲100的字符串 S 32 cin>>s; //輸入字符串 S 33 Node num[51]; //由於字符串S最多包含26個小寫字母,因此整個哈夫曼樹的結點最多爲51個 34 for(int i=0;i<51;i++){ 35 num[i].lchild=num[i].rchild=num[i].parents=NULL; //初始化樹結點的左右子結點、雙親結點 36 } 37 int vis[200]; //定義標記數組 38 memset(vis,0,sizeof(vis)); //初始化標記數組 39 int t=0; //用 t 來記錄當前有多少個樹結點 40 for(int i=0;i<strlen(s);i++){ 41 if(num[s[i]-'a'].value==0) t++; //統計多少個不一樣的字符 42 num[s[i]-'a'].data=s[i]; 43 num[s[i]-'a'].value++; //統計s[i]字符出現的次數,即s[i]字符的權值 44 } 45 for(int i=0;i<25;i++){ //由於小寫字母只有26個,所以最多找25次,因此循環只須要最多25次便可 46 int min_value1=INF; //初始化權值無窮大 47 int min_value2=INF; //初始化權值無窮大 48 int x,y; //x,y表示最小值和次小值 49 x=y=-1; //初始化x,y 50 for(int j=0;j<51;j++){ //最多遍歷51個結點,尋找最小值和次小值 51 if(min_value1>num[j].value&&!vis[j]&&num[j].value!=0){ 52 y=x; 53 min_value2=min_value1; 54 x=j; 55 min_value1=num[j].value; 56 }else if(min_value2>num[j].value&&!vis[j]&&num[j].value!=0){ 57 y=j; 58 min_value2=num[j].value; 59 } 60 } 61 if(y==-1) break; //說明只剩下一個結點了,能夠跳出循環 62 num[t++].value=num[x].value+num[y].value; 63 vis[x]=vis[y]=1; //標記已經加入哈夫曼樹的樹結點 64 root=insert_huffman_tree(&num[t-1],&num[x],&num[y]); //將樹結點插入哈夫曼樹 65 } 66 cout<<"輸入的字符串的各個字符的哈夫曼編碼是:"<<endl; 67 get_huffman_code(root); //獲取並打印字符的哈夫曼編碼 68 return 0; 69 }
測試結果:ios