1. 程式人生 > >求哈弗曼樹的編碼

求哈弗曼樹的編碼

哈弗曼 編碼 class strcpy HA span -s 結點 scan

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #define N 20
  5 #define M 2*N-1
  6 typedef struct
  7 //哈夫曼樹的類型定義
  8 {
  9     int weight;
 10     int parent;
 11     int LChild;
 12     int RChild;
 13 }HTNode,HuffmanTree[M+1];
 14 typedef char *HuffmanCode[N+1
]; 15 void CrtHuffmanTree(HuffmanTree ht,int w[],int n)//構造哈夫曼樹ht[M+1],w[]存放n個權值 16 17 { 18 int i,k,Lnode,Rnode,Min1,Min2,max=0; 19 int m=2*n-1; 20 for(i=1;i<=n;i++) //葉子結點初始化 21 { 22 ht[i].weight=w[i]; 23 ht[i].parent=0; 24 ht[i].LChild=0; 25 ht[i].RChild=0
; 26 } 27 /[i]={ w[i],0,0,0}; 28 for(i=n+1;i<=m;i++) //非葉子結點初始化 29 /[i]={0,0,0,0}; 30 { 31 ht[i].weight=0; 32 ht[i].parent=0; 33 ht[i].LChild=0; 34 ht[i].RChild=0; 35 } 36 37 38 /* 39 40 for(i=1;i<=m;i++) 41 {
42 printf(" %d,",w[i]); 43 } 44 printf(" %n"); 45 for(i=1;i<=m;i++) 46 { 47 printf(" %d,",ht[i].weight); 48 } 49 printf(" %d\n",max); 50 51 */ 52 53 54 55 for(i=n+1;i<=m;i++)//建立哈夫曼樹 56 { 57 Min1=Min2=10000; 58 Lnode=Rnode=0;//Lnode存放最小值的位置,Rnode存放第二最小值的位置 59 for(k=1;k<i;k++)//只在尚未構造二叉樹的結點中查找最小的兩個結點 60 { 61 if(ht[k].parent==0) 62 { 63 if(ht[k].weight<Min1)//查找當前最小值 64 { 65 Min2=Min1; 66 Rnode=Lnode; 67 Min1=ht[k].weight; 68 Lnode=k; 69 } 70 else 71 if(k!=Lnode&&ht[k].weight<Min2)//查找當前第二最小值 72 { 73 Min2=ht[k].weight; 74 Rnode=k; 75 } 76 } 77 } 78 ht[i].weight=Min1+Min2; 79 ht[i].LChild=Lnode;ht[i].RChild=Rnode; 80 ht[Lnode].parent=i;ht[Rnode].parent=i; 81 } 82 printf("\n哈夫曼樹的終態\n序號\tWeight\tParent\tLChild\tRChild\n"); 83 for(i=1;i<=m;i++)//測試代碼 84 { 85 printf("%d",i); 86 printf(" %d",ht[i].weight); 87 printf(" %d",ht[i].parent); 88 printf(" %d",ht[i].LChild); 89 printf(" %d",ht[i].RChild); 90 printf("\n"); 91 } 92 printf("\n"); 93 94 95 } 96 void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n) 97 //從葉子結點到根,逆求每個葉子結點對應的哈夫曼編碼,左0右1 98 { 99 char *cd; 100 int i,j,c,p,start; 101 cd=(char *)malloc(n*sizeof(char)); 102 cd[n-1]=\0; 103 for(i=1;i<=n;i++) 104 { 105 start=n-1; 106 c=i;p=ht[i].parent; //尋找該葉子結點的父母 107 while(p!=0) 108 { 109 --start; 110 if(ht[p].LChild==c) 111 cd[start]=0;//判斷是左邊還是右邊 112 else 113 cd[start]=1; 114 c=p;p=ht[p].parent;//繼續向上倒推 115 } 116 hc[i]=(char *)malloc((n-start)*sizeof(char)); 117 //strcpy(hc[i],&cd[start]); 118 for(j=0;j<n-1;j++) 119 { 120 if(cd[j]==0||cd[j]==1) 121 printf("%c",cd[j]); 122 } 123 printf("\t"); 124 for(j=0;j<n-1;j++) 125 { 126 cd[j]= ; 127 } 128 } 129 free(cd); 130 } 131 void main() 132 { 133 HuffmanTree ht1; 134 HuffmanCode hc; 135 char ch[20]; 136 int i,a,w[20]; 137 printf("請輸入字符個數(小於20):"); 138 scanf("%d",&a); 139 printf("請輸入字符:"); 140 getchar(); 141 for(i=1;i<=a;i++) 142 { 143 ch[i]=getchar(); 144 } 145 getchar(); 146 printf("請輸入各個字符對應的權值:"); 147 for(i=1;i<=a;i++) 148 { 149 scanf("%d",&w[i]); 150 } 151 CrtHuffmanTree(ht1,w,a); 152 printf("\n\t\ts對各字符的哈夫曼樹編碼\n"); 153 printf("\t字符\t"); 154 for(i=1;i<=a;i++) 155 { 156 printf("%c\t",ch[i]); 157 158 } 159 printf("\n\t權值\t"); 160 for(i=1;i<=a;i++) 161 printf("%d\t",w[i]); 162 printf("\n 哈夫曼編碼\t"); 163 CrtHuffmanCode(ht1,hc,a); 164 printf("\n"); 165 }

求哈弗曼樹的編碼