Skip to content

Commit 6df7548

Browse files
committed
实现了Huffman编码过程
1 parent dd0a797 commit 6df7548

File tree

2 files changed

+238
-48
lines changed

2 files changed

+238
-48
lines changed

Huffman/main.c

Lines changed: 237 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,65 +11,238 @@ typedef struct Node
1111
{
1212
ElemType data;
1313
int num;
14+
char *code;
1415
struct Node *l_chlid;
1516
struct Node *r_child;
1617
struct Node *next;
1718
}Node, *HufQueue, *HufTree;
1819

20+
void printCode( HufTree *T )
21+
{
22+
Node *n;
23+
n = (*T);
24+
25+
if( n->l_chlid == NULL && n->r_child == NULL )
26+
{
27+
printf("元素 %c 编码为 \" %s \". \n", n->data, n->code );
28+
}
29+
else
30+
{
31+
printCode( &n->l_chlid );
32+
printCode( &n->r_child );
33+
}
34+
}
35+
36+
//给字符串添加字符
37+
char * addCode( char *str, char code )
38+
{
39+
int i;
40+
char *buf;
41+
int len = strlen( str );
42+
buf = (char *)malloc( len * sizeof(char));
43+
44+
for( i=0; i<len; i++ )
45+
{
46+
buf[i] = str[i];
47+
}
48+
buf[len] = code;
49+
buf[len+1] = '\0';
50+
return buf;
51+
}
52+
53+
//对Huffman树进行编码
54+
void encode( Node **n, char *c )
55+
{
56+
if( c == NULL )
57+
{
58+
c = (char *)malloc(sizeof(char));
59+
c[0] = '\0';
60+
}
61+
62+
Node *x;
63+
x = (*n);
64+
char l_code = '0';
65+
char r_code = '1';
66+
67+
x->code = (char *)malloc(sizeof(char));
68+
x->code = c;
69+
70+
if( x->l_chlid != NULL )
71+
{
72+
encode( &x->l_chlid, addCode( c, l_code ) );
73+
}
74+
if( x->r_child != NULL )
75+
{
76+
encode( &x->r_child, addCode( c, r_code ) );
77+
}
78+
}
79+
1980
//将元素放入合适的位置,按大小顺序排列
2081
void push( HufQueue *Q, Node **n )
2182
{
22-
Node *x, *y;
83+
HufQueue x = NULL;
84+
Node *y;
2385
x = (*Q);
86+
87+
if( x->next == NULL )
88+
{
89+
x->next = (*n);
90+
return;
91+
}
92+
2493
while( x->next != NULL )
2594
{
2695
y = x;
2796
x = x->next;
2897

29-
if( (*n)->num < x->num )
98+
if( (*n)->num <= x->num )
3099
{
31100
(*n)->next = x;
32101
y->next = (*n);
33102
break;
34103
}
104+
105+
if( x->next == NULL )
106+
{
107+
x->next = (*n);
108+
break;
109+
}
35110
}
36111
}
37112

38113
//获取最小的元素,也就是第一个元素。
39-
void get( HufQueue Q, Node **n )
114+
void get( HufQueue *Q, Node **n )
40115
{
41-
(*n) = Q->next;
116+
HufQueue q = NULL;
117+
q = (*Q);
118+
119+
if( q->next != NULL )
120+
{
121+
(*n) = q->next;
122+
q->next = q->next->next;
123+
}
124+
else
125+
{
126+
(*n) = NULL;
127+
}
42128
}
43129

44-
//带权的链表生成Huffman树
130+
//带权的链表生成Huffman树 想递归实现
45131
void createTree( HufTree *T, HufQueue *Q )
46132
{
133+
HufQueue q = NULL;
134+
HufTree t = NULL;
47135
Node *x, *y;
48136
Node *n;
49137

50-
(*T) = (HufTree)malloc(sizeof(Node));
138+
q = (*Q);
139+
t = (*T);
51140

52-
get( *Q, &x );
53-
get( *Q, &y );
141+
get( &q, &x );
142+
get( &q, &y );
54143

55-
n->num = x->num + y->num;
144+
//test
145+
printf("\n--------------------------------\n");
146+
if( x != NULL)
147+
{
148+
printf("x data: %c = %d ", x->data,x->num);
149+
}
150+
printf(" ... ");
151+
if( y != NULL )
152+
{
153+
printf("y data: %c = %d ", y->data,y->num);
154+
}
155+
printf("\n--------------------------------\n");
56156

57-
if( x->num < y->num )
157+
if( x != NULL && y == NULL )
58158
{
59-
n->l_chlid = x;
60-
n->r_child = y;
159+
(*T) = (HufTree)malloc(sizeof(Node));
160+
(*T)->next = x;
61161
}
62162
else
63163
{
64-
n->l_chlid = y;
65-
n->r_child = x;
164+
n = (Node *)malloc(sizeof(Node));
165+
166+
n->num = x->num + y->num;
167+
168+
if( x->num < y->num )
169+
{
170+
n->l_chlid = x;
171+
n->r_child = y;
172+
}
173+
else
174+
{
175+
n->l_chlid = y;
176+
n->r_child = x;
177+
}
178+
n->data = '\\';
179+
n->next = NULL;
180+
181+
push( &q, &n );
182+
183+
createTree( &t, &q );
66184
}
67-
n->data = '\\';
68-
n->next = NULL;
185+
}
69186

70-
push( Q, &n );
187+
//带权的链表生成Huffman树 迭代实现
188+
void createTree2( HufTree *T, HufQueue *Q )
189+
{
190+
HufQueue q = NULL;
191+
Node *x, *y;
192+
Node *n;
193+
194+
q = (*Q);
195+
196+
get( &q, &x );
197+
get( &q, &y );
198+
199+
while( 1 )
200+
{
201+
//test
202+
/*
203+
printf("\n--------------------------------\n");
204+
if( x != NULL)
205+
{
206+
printf("x data: %c = %d ", x->data,x->num);
207+
}
208+
printf(" ... ");
209+
if( y != NULL )
210+
{
211+
printf("y data: %c = %d ", y->data,y->num);
212+
}
213+
printf("\n--------------------------------\n");
214+
*/
215+
216+
if( x != NULL && y == NULL )
217+
{
218+
(*T) = (HufTree)malloc(sizeof(Node));
219+
(*T) = x;
220+
break;
221+
}
222+
223+
n = (Node *)malloc(sizeof(Node));
224+
225+
n->num = x->num + y->num;
226+
n->data = '\\';
227+
n->code = NULL;
228+
n->next = NULL;
229+
230+
if( x->num < y->num )
231+
{
232+
n->l_chlid = x;
233+
n->r_child = y;
234+
}
235+
else
236+
{
237+
n->l_chlid = y;
238+
n->r_child = x;
239+
}
71240

241+
push( &q, &n );
72242

243+
get( &q, &x );
244+
get( &q, &y );
245+
}
73246
}
74247

75248
//初始化原始队列
@@ -89,6 +262,7 @@ void initQueue( HufQueue *q, char (*cou)[2] )
89262
(*q)->l_chlid = (*q)->r_child =(*q)->next = NULL;
90263
(*q)->num = len;
91264
(*q)->data = '#';
265+
(*q)->code = NULL;
92266

93267
x = (*q);
94268

@@ -97,6 +271,7 @@ void initQueue( HufQueue *q, char (*cou)[2] )
97271
y = (Node *)malloc(sizeof(Node));
98272
y->data = cou[j][0];
99273
y->num = cou[j][1];
274+
y->code = NULL;
100275
y->l_chlid = y->r_child = y->next =NULL;
101276
x->next = y;
102277
x = y;
@@ -190,58 +365,73 @@ void mySort( char (*cou)[2] )
190365

191366
int main()
192367
{
193-
int i, len;
368+
//int i, len;
194369
char str[256];
195370
char cou[128][2];
371+
char *flag = NULL;
372+
196373
HufQueue Q = NULL;
197374
HufTree T = NULL;
198375

376+
printf("请输入您需要编码的讯息:\n");
377+
199378
getInput( str );
200379

201380
count( str, cou );
202381

203382
mySort( cou );
204383

205-
//打印一下排好序的原始数组。
206-
len = cou[0][1];
207-
for( i=0; i<len+1; i++ )
208-
printf("%c ", cou[i][0]);
209-
printf("\n");
210-
for( i=0; i<len+1; i++ )
211-
printf("%d ", cou[i][1]);
212-
printf("\n");
213-
214384
//初始化带权的链表。
215385
initQueue( &Q, cou );
216386

387+
//带权的链表生成Huffman树
388+
createTree2( &T, &Q );
389+
390+
//对各个字符进行编码
391+
encode( &T, flag );
217392

393+
//打印每个元素的编码
394+
printCode( &T );
218395

219-
/* 测试push函数
220-
Node *n = NULL;
221-
n = (Node *)malloc(sizeof(Node));
222-
n->l_chlid = n->r_child = n->next = NULL;
223-
n->data = '\\';
224-
n->num = 2;
225-
push( &Q, &n );
396+
return 0;
397+
}
398+
399+
400+
/*
401+
测试push函数
402+
Node *n1 = NULL;
403+
n1 = (Node *)malloc(sizeof(Node));
404+
n1->l_chlid = n1->r_child = n1->next = NULL;
405+
n1->data = '\\';
406+
n1->num = 2;
407+
push( &Q, &n1 );
226408
227409
while( Q->next != NULL )
228410
{
229411
Q = Q->next;
230-
printf("%d", Q->num);
412+
printf("data: %c = %d \n", Q->data,Q->num);
231413
}
232414
*/
233415

234-
/* 测试get函数
235-
printf("%d", Q->next->next->num);
236-
237-
Node *n = NULL;
238-
n = (Node *)malloc(sizeof(Node));
239-
get(Q,&n);
240-
printf("%d",n->num);
416+
/*
417+
测试get函数
418+
Node *n2 = NULL;
419+
n2 = (Node *)malloc(sizeof(Node));
420+
get(&Q,&n2);
421+
while( Q->next != NULL )
422+
{
423+
Q = Q->next;
424+
printf("data: %c = %d \n", Q->data,Q->num);
425+
}
241426
*/
242427

243-
//带权的链表生成Huffman树
244-
createTree( &T, &Q );
245-
246-
return 0;
247-
}
428+
/*
429+
打印一下排好序的原始数组。
430+
len = cou[0][1];
431+
for( i=0; i<len+1; i++ )
432+
printf("%c ", cou[i][0]);
433+
printf("\n");
434+
for( i=0; i<len+1; i++ )
435+
printf("%d ", cou[i][1]);
436+
printf("\n");
437+
*/

task.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
ʮ��BF�㷨 ok BF
1111
ʮһ��������ʵ�� ok BTree
1212
ʮ��������������ʵ�� BTree2
13-
ʮ�����շ������� Huffman
13+
ʮ�����շ������� ok Huffman

0 commit comments

Comments
 (0)