a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 125|回复: 1

[C语言] 常用算法之哈夫曼算法

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
  #include
& g4 }2 X% ]/ _, m, {  #include
+ r% v1 k5 {" ^/ _  #include
" |# P* y/ y7 g$ b) Y  #include7 H( [7 z5 p! N- [8 g
  #include9 j8 {$ d" Q& J! E
  /*声明两种链表结构----start*/. o# v# L5 ^7 N. x
  struct node_a{ /*链表1-----作用:用来统计文件中字符的个数和种类(通过count)*/2 }' Q5 F3 k/ \% ?! X
  char data;6 i3 c( p) w& |# M+ q* j4 n5 j+ r: }5 {  y
  int count;! n  y* U% h2 I& e$ n
  struct node_a *next;% n9 s: T8 ], F8 c
  };, k- F1 ]" l) S' J, L! y* @+ W
  typedef struct node_a node,*list;* }0 |3 Q( b* V" t: Q
  list head=NULL;
4 c# U" O- C* q! d& f  Z  struct nodeb{ /*链表2-----作用:用来建立用相应的编码代替字符的新文件*/; a! r; D4 w( i2 u4 O0 T2 n: i
  char data;; b! I$ t2 K+ s4 A5 Y: d$ Y9 w
  struct nodeb *next;+ S* g$ K% p6 P# v
  };
4 X4 n# \1 Z+ R$ o$ c- k  typedef struct nodeb node_b,*list_b; /*jiang bianma xieru wenjian*/
* Q8 H9 O& {1 }" y  list_b head_b=NULL;
% R& @6 E$ a; }& j8 _: l* b  /*声明两种链表结构----end*/1 B2 O* F5 @4 m6 Q$ X+ R/ W
  /*哈夫曼算法种相关的3种结构的声明-----start*/
. \! N9 u0 B& D  struct forest{! r3 c; R0 \* \( @+ `8 y, T5 v
  float weight;
2 ~# ]& X" o3 I  int root;" M" h6 p1 ^% g$ C/ V* l
  };
. k9 _* X. I2 `, u4 I  struct alphabet{
9 z+ d8 H0 P, g! x0 P5 `9 c. E  char symbol;5 @$ k8 V  s. Q, `# |4 W
  float probability;
, w. _5 u3 ?$ C: I  int leaf;
8 d# o6 {9 L6 ^0 V  char *bianma;3 ~' R8 [" O$ r3 S1 t4 G6 b: f
  };
, }0 G" U9 v' G8 r- z  struct tree{
% r5 I3 p" M) P+ Z$ q  int lchild;
& q$ ~3 C( |* T0 A  int rchild;& K$ I) B- |0 d, i# o- z
  int parent;, m6 F/ s! F. ~. f9 |6 g
  };
0 \7 K7 n! I( {& @8 Q  typedef struct tree *tree_ptr,tree_node;
" o* t: H# C4 N/ }% o0 \  typedef struct forest *forest_ptr,forest_node;
* o/ r+ s$ F( P- w! q1 B$ V  typedef struct alphabet *alphabet_ptr,alphabet_node;' c9 s& m- V5 p6 F8 g& M0 Z9 n/ L+ j) Y
  tree_ptr tree1;
) m& E$ @; M8 g  forest_ptr forest1;7 k# j0 E% v( P' `# X# j/ d' j
  alphabet_ptr alphabet1;1 e0 l5 N" d6 H/ o1 R" n
  int lasttree,lastnode;/ n1 f# t3 \9 E2 U( Q
  int least,second;
9 `8 z9 M$ M  C! N$ a4 {4 P' u  /*哈夫曼算法种相关的3种结构的声明-----end*/
; {, t8 T. h$ E# }2 g% Y  /**************stack difination start****************/3 W* {  i- }" P. o! S5 B7 K" J* h
  struct stacknode{
- Z1 J; z$ a$ r  char *bian_ma;3 ?6 L9 I+ C6 z& \
  struct stacknode *next;' M% {2 B9 o3 r) h! a0 D, w
  };" t8 h: ?4 [2 r+ `
  typedef struct stacknode stack_node;
8 K, ?. W3 b, ?1 B$ a0 L" w9 p: e  typedef stack_node *link;; B0 b2 u% _- ]; _; H, ?/ z
  link top=NULL;
# Z9 g( {! R- ^# c! t: z& ?, m; z  void push(char *item){$ f7 T$ G! ~/ M1 }7 f% ?& \( W8 b+ }
  link p;
  z" F+ z& t: b  if(top!=NULL){
# b" R/ F$ {$ w4 C! s1 v  p=(link)malloc(sizeof(stack_node));
8 ]3 p2 f/ K1 \0 Q  if(p==NULL){( ~, T3 g- w8 s5 X* x* y# m
  printf("Memory allocation error!");( o- }) U" P+ Y* E
  return;8 y5 i# M: p2 m8 L9 {
  }
4 z! C7 d8 q/ S  p->bian_ma=item;; ^+ ]4 _4 p, u9 U6 s7 j: u/ {4 [
  p->next=top;$ A3 m( K0 p" S, ?: T  l/ k6 ~# ^8 u& \
  top=p;* o8 X: E- v! p$ `+ D6 ?
  }1 t0 }  I/ m3 \: P2 v# O
  else{, l. v6 E* B/ Y; n: L  w4 H
  top=(link)malloc(sizeof(stack_node));8 }0 u& l* Y- \# |& ~# E" I. y
  if(!top){
$ G( j) D- @0 F2 c  ^) T6 a6 V  printf("Memory allocation error!");
! Y0 o/ Y5 _& A# N/ K0 F  return;
& V  n1 `- t/ {- [4 Y% d7 `  }
( g4 r7 l% R3 q5 N: k) P; X% R  top->bian_ma=item;
1 j& _# G# m! ~! g( P  top->next=NULL;9 G% p! F5 y: d" w, q7 m6 {/ Z
  }9 d& ^( p) X6 B6 L" K
  }" g: v) Z4 W' R4 I& K8 C
  void pop(void){! {9 V2 \$ F8 k/ ~5 h% Y' P, A
  link p;  K' B1 W. Z8 ?  Z3 P' \4 ]- j8 b
  p=top;
8 i7 H. y4 h6 s  U+ n  top=top->next;
& N  {3 f$ e' J% B% z  free(p);! Z3 d. P( `4 H
  }+ r. M% d2 z! Y/ _% m
  void makenull(void){/ K0 \* W) y% Q. M
  while(top!=NULL)
9 X6 T6 T( |+ o, v, g" N, A  pop();
/ R2 t% w0 i) R4 P6 w  }& O' b8 ?, G" Z$ Q8 R, ]3 B
  int empty(){3 J: k1 Y* _6 V
  if(top==NULL): k+ s* l8 X: p/ N
  return 1;
# C9 Y* R+ X! V5 P" i  else6 Y7 i! g% G# {: [
  return 0;  n$ z9 P# f1 \6 A/ [
  }
. I1 }' W( T( }/ t9 `" |& D  char* tops(void){
: Z0 R/ E$ h( v# w; H7 u0 l  return (top->bian_ma);
2 ]: h8 Z* i2 T  }
+ R2 v9 U$ L4 x* a  P4 P  void display_stack(link s){ /*显示栈重的内容*/
# Q8 v  u2 b& K  {# e( s2 Q  link ptr;0 V5 M0 P# x/ k. r) i! E
  ptr=s;
+ j' T, R' @$ `6 g  while(ptr!=NULL){
1 S; h1 C% T1 \7 V  printf("%s",ptr->bian_ma);6 X3 n& ], p: T( e- i' ], z
  ptr=ptr->next;( O( O: K4 F/ ]! D
  }
: b2 D7 Y0 W4 _) l2 V8 o$ }  }. e  z  K4 f' P
  /***************************stack__difination is end************************/& m, s5 `4 S8 L! L8 R, i
  void display(list h){ /*显示链表1*/6 }7 N- R5 Z; _- Z
  list ptr;6 ^% S- J6 p, S9 o9 M
  int i=1;% d+ f+ F# Y, G% l4 s; m/ ~- J4 x
  ptr=h->next;
, O" f7 N* |7 K; I  while(ptr!=NULL){
; C3 h8 M2 Q* a! l1 F5 l) ?9 F  printf("%d,%c,%d\n",i,ptr->data,ptr->count);* C& p8 r; S3 C2 S( M' Q
  i++;
; {# X+ r) r- H/ {# d  ptr=ptr->next;0 m4 z5 q8 {# n$ ]( U$ P: f
  }
5 x( F/ l$ ?8 a6 w- z  }2 N, f; |3 l. ?+ l0 z! w; {% F
  void display_b(list_b h){ /*显示链表2*/
7 S0 ^# T+ d4 s" b  list_b ptr;5 A/ F/ K4 j7 X, m4 b4 V6 h) r
  int i=1;
, v3 G) ~- Z8 {. ?  ptr=h->next;
) N, P) |) q1 l" d( s  {- c  while(ptr!=NULL){4 |2 {+ K; s1 w: Q; G% U3 ~# L
  printf("%d,%c\n",i,ptr->data);, o$ X! k  Y; _. G
  i++;7 ^9 ?5 x! A- Y' u
  ptr=ptr->next;, n6 Z" ^; d* Q" w
  }
# H, C/ B( q6 C; G) R* K  }& W9 f+ B* M9 d, o
  void insert(char item){ /*用于插入元素以建立链表1*/9 _9 ~3 V) d/ i6 C
  list temp,ptr;: P) @4 r- q9 a% X! |4 z. B5 h9 v
  int flag;  l7 Q  h  H0 b$ c8 |4 r
  ptr=head->next;& L5 \2 q! V9 i
  if(ptr==NULL){: E3 F2 R2 i4 k- T& w2 Z
  head->next=(list)malloc(sizeof(node));4 ]9 y* [/ E* \1 @! C
  head->next->data=item;
1 _% u) W( h0 e  N  head->next->count=1;
9 B3 x) d/ j/ K2 \4 O% P  head->next->next=NULL;
' T% z( r( z: S' @8 q8 ~  }
$ q9 x/ T" x9 {$ `& i% \) J$ `  else{- B% i. A( ]- j# f
  while(ptr!=NULL){; b" b2 t( i1 c# W8 U" G
  if(ptr->data==item){0 }- ]- Y$ j1 f5 k- K* N6 u
  ptr->count=ptr->count+1;
! \8 Y" {- \1 O1 W  flag=1;
" L9 e* ]/ H" w% b. a# p- @8 @" ]  }+ Y% w" @( D1 h. @) B
  ptr=ptr->next;
* Q' }! L' H+ Q- H  }6 H% k# Y$ K3 G
  ptr=head;
! K$ \! D6 p! J! ^! ?" Z  if(flag==1)( q8 T+ M: p9 w" K) b& E
  return;1 a4 b4 _1 d4 a* @; h1 x
  else{
' F  ?& {8 L( ^1 P7 C  temp=ptr->next;
9 n' m2 f3 L- @9 m: b  ptr->next=(list)malloc(sizeof(node));
, d/ u; n# w  k0 y  P' a9 P: d' _  ptr->next->data=item;# {# l* c# r% {4 P4 q% m
  ptr->next->count=1;
' u& b5 [# O- ]( n3 F  ptr->next->next=temp;
( i: J1 s3 T. E6 M# {$ b' @  }: Y1 a" M, R5 F( ~
  }
% W  g, l  @: y5 o% h6 J- g1 B* @3 I  }
8 `- B6 C( e7 h9 N# E" i1 z1 D  v7 }, `3 M" `
  void insert_b(char item){ /*插入元素以建立链表2*/
; x% \4 n: ?3 N  list_b ptr_b, temp_b;
5 b( `. L! V7 B( s* |  ptr_b=head_b;
" z" J* y* L5 P& n% d9 E  if(ptr_b->next==NULL){5 s1 ?( c3 b# `! b/ M" @+ a! S
  head_b->next=(list_b)malloc(sizeof(node_b));) l7 \. Y# }) s$ F7 E# k! h
  head_b->next->data=item;
& b, Q* f$ B! g5 o8 H  head_b->next->next=NULL;
1 O% e( m$ Y  C8 p& S  }
/ Q+ ~1 x6 V6 v4 T( O3 d& H* y  else{
; d( a; e9 T' o* U7 O- c0 `  while(ptr_b->next!=NULL){9 v6 {/ ?& b: ^6 A2 F3 G' W! M" d2 u
  ptr_b=ptr_b->next;
5 X, C+ d  G  A  y, E- r' C( F  }8 l2 r9 V/ J, b
  ptr_b->next=(list_b)malloc(sizeof(node_b));
/ f) {3 F! e2 l. y2 [  v+ y7 L  ptr_b->next->data=item;
/ `+ ~" X8 L4 E  ptr_b->next->next=NULL;
% \7 V2 }: M6 @8 o# S  }
) _3 {! D; o& i8 n0 k  }
4 M, ?5 i4 ~4 W) r( g$ P  void search(void){ /*搜索文件并将文件中的数据分别存入作用不同的链表中*/! T3 T1 {: ^5 v: C  v% o, N0 r
  FILE *fp;
6 z3 G+ J3 s* r$ ~7 H# W  _8 `  list ptr;- @. l. S8 i5 {/ z, Z
  char ch;
' c8 L, q/ c7 Y1 c" N+ b  if((fp=fopen("test.txt","r"))==NULL)! y7 W" ~* H' T- {
  printf("Reading error!\n");+ O/ X: t5 ~5 X% z0 D3 s- J8 z
  while(!feof(fp)){
9 ~  ?! A' i9 G0 u8 t6 s/ p  ch=getc(fp);
5 J3 R: o+ O& o: e# a  if(ferror(fp)){+ i$ G2 }! X1 d* f5 w8 i
  printf("error!\n");
2 F' _* J6 x. U9 k. ~  break;4 K9 L" x! V2 U" [  r) T0 o) H6 i
  }' G$ H- T) d0 C* F- n" A
  if(ch==EOF)5 k9 I( B& l. y' y% P4 m1 T- V- h
  break;3 T" t% Y: C& N* e' v* d$ t1 I
  insert(ch); /*插入元素进链表1*/
回复

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:09 | 显示全部楼层

常用算法之哈夫曼算法

  insert_b(ch); /*插入元素进链表2*/+ }1 b+ V* q0 N) a2 I' W
  }
: M: |0 n8 W. h8 D  printf("\n");, s; }" b* d9 Y. o
  fclose(fp);& C$ _7 [7 N% n1 a2 x: P4 m2 ~
  }
8 X0 x' C) V- e) b  void display_struct(int n){ /*显示哈夫曼算法中的3个结构树组 */
$ Q& X* `+ L( ^; S4 b  int i=0;
6 n' R' I/ B- {  printf("\n\n=======================================\n\n");
% x0 I! B( Q0 l  printf("FOREST_STRUCT_ARRY :\n\n\n");' n* D- r0 c; z" u' U5 F
  for(i=0;inext;
, k. c9 j% h9 H  i( X  while(ptr!=NULL){* Y4 T; W* ~4 h. W
  count=ptr->count+count;) a7 \# X2 X3 N
  n++;
* n! j4 j, x- X) S, O! r3 A  ptr=ptr->next;; D" }+ H( ~: Q, ]
  }</p>  ptr=head->next;/ n  V1 k% {9 z* @% D. e
  forest1=(forest_ptr)malloc(sizeof(forest_node)*n+sizeof(forest_node));
3 _5 S- D' s; \5 _  alphabet1=(alphabet_ptr)malloc(sizeof(alphabet_node)*n+sizeof(alphabet_node));  `4 ~! W& m) |1 s$ S- S4 X
  tree1=(tree_ptr)malloc(sizeof(tree_node)*n*2-sizeof(tree_node));8 p& a+ P4 G( k0 q0 N6 M% m; S5 c
  forest1[0].weight=alphabet1[0].probability=0.0;3 E9 {/ D5 j9 K0 O9 K
  forest1[0].root=alphabet1[0].leaf=0;3 o$ U' s6 n9 m1 l
  alphabet1[0].symbol='0';7 M# q- f4 @# r1 E. X
  while(ptr!=NULL){
2 b5 q; I; f( A: H- N+ x  forest1.weight=alphabet1.probability=ptr->count/count;
, O, P1 Q) s' S0 t" z) Y  forest1.root=alphabet1.leaf=i;
5 Y* h0 Q+ v& ]% a  alphabet1.symbol=ptr->data;1 t* K  A" j7 \; }2 E
  i++;/ m3 U! k+ Y! Y3 y- B  K1 ?
  ptr=ptr->next;2 p- Y( l. i; `7 h* M$ f$ l
  }
" g& C; ?4 d3 x5 ]5 Y! S  for(i=0;inext;
2 d, s4 ~% K8 C& {  if((fp=fopen("bianma.txt","w"))==NULL)
' w+ {1 d1 v2 o* ~- I5 K+ n. b  printf("Write in a new file error!");
- b9 @2 s  e3 j: w, w% _  else{3 U; R9 a- j+ e. `1 J9 c
  while(ptr!=NULL){- r6 K% j9 \- N8 [
  for(i=1;idata==alphabet1.symbol){
6 u6 s1 v) [( N# ?& {" t  strcpy(ch,alphabet1.bianma);. ]) z8 B' o0 p7 s7 ~
  fputs(ch,fp);
" k, [' Y  N- }: |  }
3 J' ?; J% z* r3 Z  }. ?- s: o$ }7 c9 k0 u) L: t: v- E0 m$ ^
  ptr=ptr->next;  {0 Z: Q3 m6 O$ d
  }! p3 n* z3 c. O
  }- p0 v5 o7 I  Z( e
  fclose(fp);' H  D0 P8 `* ~5 z" Y) |
  }/ Z9 u8 ~3 n* h2 _* e7 c3 J
  void main(void){! h! f% E* S# E+ ?9 R( a& b+ Y
  int i,num;
5 m, q1 p6 M& Q: O: c- x  char ch;
/ ]$ H! K- y* S8 G4 d# d5 z  void huffman(void);+ t% G% \6 \, U2 [0 \
  void lightones();+ F/ ~( @4 z( Y( x5 z; A% u/ D
  head=(list)malloc(sizeof(node));
2 v. R, ]' Z; l  head->next=NULL;9 i6 y* {( Q: {% r8 [/ @+ F1 E
  head->data='\0';3 ^7 r3 a4 ~9 n  B3 q/ d$ q  \
  head->count=0;
1 L8 S" n" U/ I3 g9 i  head_b=(list_b)malloc(sizeof(node_b));7 g: f' ?6 T! {5 ^
  head_b->data='\0';& m9 @/ h* K2 o4 ~+ \
  head_b->next=NULL;
2 u" J* P: P9 P$ H( i( ?; F: X) K  do{. L( D; w- O7 w, @
  system("cls");4 v. f$ g& {) P) d7 _. V( I
  creat();
( d4 h0 e" J* |& Y- f/ S- S+ L' L  search();
4 ]( n) t, J2 b  j/ k  printf("\nlianbiao1:\n");( `3 @5 @7 H& @% P% X, }) a4 D+ n# \
  display(head);/*显示链表1*/; _6 c1 ?  v; \: [
  getch();
& R# }2 a( U7 X8 y% k& f  printf("\nlianbiao2:\n");
. G  J) U# J$ F3 W: Z6 f: U  display_b(head_b);
& o- P! t2 H+ @$ z3 m  getch();
' C, w% v0 y& e) Q6 P# X  num=init_struct();
$ p  }3 B, D* m6 q  printf("\n");
3 C) h: B! Q! D& @; V! |) Z  printf("The 3 init_struct of huffman?\n");
+ ~' G8 f. X8 P- G3 K$ r% F' p; l  display_struct(num);/*显示初始化的哈夫曼书的相关3个结构数组*/
) C% h5 T" c" E( K2 ^7 a8 i) R  lastnode=num;4 Y* Q' J, I9 L
  lasttree=num;
7 q/ W( r! o$ i7 A  huffman();7 R5 A& Y8 v. z0 A; o7 s& L7 B& F
  printf("Now the 3 struct through huffman shuanfa\n");
+ z" B- U( \" _' E9 Y$ c9 n  display_struct(num);/*显示哈夫曼树中相关的3种结构(经过哈夫曼算法处理)*/: w4 i5 d* N! }
  printf("\nThe bian_ma is:\n");6 c5 t9 A9 }& i% q% J$ S
  creat_bianma(num);
; ?1 x0 U5 c+ F+ O/ q3 t5 J- X: Z  write_new_file(num);6 ~' s6 y8 x3 p- i# e* X
  printf("\nDo you want to re_try(y/n)?");
7 z5 x  Q3 I! C5 B' n4 p) ^/ K. c  ch=getchar();& ?6 `4 c; b5 f- z( [
  }while(ch=='y');6 T& {& c1 Z, Y+ e3 y- q1 p
  }
; j, G: j0 _7 \9 j1 O( c" [  /*哈夫曼算法-----defination_start*/1 z8 k! ?5 `+ b, f! P% ?- f
  void lightones(void){8 p2 r& V% @% p6 u( Y+ a
  int i;0 p  c2 d( X% V& b4 m$ m, d
  if(forest1[1].weight1){
4 w1 J! h- l0 k  lightones();. ]0 r- a( r/ i  _6 O
  i=least;0 t  H& h3 j$ P. h, a$ a/ d
  j=second;
  w# f) B; h4 h2 P  newroot=creat_tree(i,j);
4 `# i6 n0 F( G  forest1.weight=forest1.weight+forest1[j].weight;
, r0 F8 ~6 P8 l( S1 v  forest1.root=newroot;& U+ L; C1 f2 d2 ]7 _- h
  forest1[j]=forest1[lasttree];. Q' v/ |6 G9 j" r% G
  lasttree=lasttree-1;5 H/ D4 _  N! |* R/ y2 P
  }# {; {- m% c" S8 t$ R
  }
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-5 05:47 , Processed in 0.397877 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表