a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 124|回复: 1

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

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
  #include
/ v8 q7 |5 M( K, q4 R( L* e/ Q; j  #include
* d, ?( f6 O2 q. O/ T: U. G  #include
  w" v8 H  {" J5 y8 p4 o  #include, N& c/ }4 N% ]0 [
  #include$ C& w9 v( J) Z6 N: k0 q' a7 R7 e" K
  /*声明两种链表结构----start*// X& v0 _6 d3 c# S! z
  struct node_a{ /*链表1-----作用:用来统计文件中字符的个数和种类(通过count)*/
5 s" u1 C5 B3 w  char data;
& T9 ?+ x  {3 ?# J  int count;. ]2 [7 Y4 |! {# z' R0 k
  struct node_a *next;
7 e  C3 ?6 a* y8 h8 w2 n6 R& \  };* `. {) b7 ^- U: K3 U/ _; c
  typedef struct node_a node,*list;# ~- m2 C) ^' y9 c( a) A
  list head=NULL;6 Z: F" d% G7 t  B2 j; X
  struct nodeb{ /*链表2-----作用:用来建立用相应的编码代替字符的新文件*/
, D; H0 M2 r& O( {6 D# q. n' C6 }  char data;" y3 f: m- T9 ~. N
  struct nodeb *next;
4 J1 ]  w/ K+ b6 S9 r  };- Q- l3 Y3 k' J% m5 B) H
  typedef struct nodeb node_b,*list_b; /*jiang bianma xieru wenjian*/! K3 L1 Q3 ?, F. l( t8 r# j8 G
  list_b head_b=NULL;
& v8 ?# v/ d0 r/ t( W6 [/ p7 Q3 N  Q: n+ s  /*声明两种链表结构----end*/
4 S8 g2 u) I3 t- S3 ?" d4 e" ~& _  /*哈夫曼算法种相关的3种结构的声明-----start*/% B+ o1 n8 h: Z/ c
  struct forest{
; M) }' B8 b- Y) `4 _+ G% C& G  float weight;
- X3 W1 S" b7 @- B  int root;
, w" D! O2 C! s6 w- J' K5 t- i0 ?2 k  };; ?: m2 G# ~* M7 f0 Y
  struct alphabet{
- y+ W$ v- W8 T& K% K, l  char symbol;
/ l) v# E. U6 r" U1 }  float probability;
) }& {+ ^2 r4 {" Q% V  c  int leaf;  `- H" z- e1 w; X" W; i8 h7 A( U: u
  char *bianma;: O. j6 p8 k& x2 g1 f1 b! v
  };
  l: o$ I0 |/ H" p2 k  struct tree{3 `( r- e$ u; P4 p# i! m
  int lchild;
$ [- L. q/ ]* m  int rchild;* W; U) W3 K) J, `$ d
  int parent;9 e" r. z; e% I. X4 u# \8 [" x
  };5 R: p4 H+ X- g; L$ S
  typedef struct tree *tree_ptr,tree_node;+ ^' `- W- m( O- G5 r( X3 u
  typedef struct forest *forest_ptr,forest_node;
. M$ S0 t' Z8 {  typedef struct alphabet *alphabet_ptr,alphabet_node;" Q) z/ W* S9 X& A, H
  tree_ptr tree1;
" F( Q1 N# C" w6 Y+ \  ]5 N5 ~  forest_ptr forest1;
, V( W1 Y+ V  ^* b0 F8 c4 q/ m4 j  alphabet_ptr alphabet1;/ w+ f8 O; E3 e8 B, u  y
  int lasttree,lastnode;
7 t2 X+ F  F; ~8 Q$ K& Z% p% I3 j( e  int least,second;3 T( W* `- W' R, d! Y* B+ V
  /*哈夫曼算法种相关的3种结构的声明-----end*/) j% ]0 q+ m8 L( s; O5 n, ?+ ~7 R9 Q
  /**************stack difination start****************/" L$ W3 T) m& p4 E! i" p
  struct stacknode{: t" {+ i6 u8 Q' t- ~+ Y4 N  ]
  char *bian_ma;7 E( M* ?( I6 J# _6 V7 e
  struct stacknode *next;/ H4 D* G6 k- \1 u
  };
4 N. ]/ O' g! `7 F1 M, P  typedef struct stacknode stack_node;% x  _) \$ O& |: H' `
  typedef stack_node *link;
# c- E& q7 A1 _* K' @6 @7 Y  link top=NULL;
3 b2 u$ l# E- B$ ]9 N  void push(char *item){
* r0 M, d. {4 D4 t$ C  link p;
! K" |  Y" m$ Z5 R# E, @  if(top!=NULL){
$ b* d5 J$ T. P9 S" X8 y7 d" R  p=(link)malloc(sizeof(stack_node));
9 ~+ G+ D8 w! G$ l; A1 @  if(p==NULL){
0 M% }* M: ~9 e  {& P  printf("Memory allocation error!");
& s! _4 D1 T4 I  x* g  x( Z  return;3 u4 ]! C. {" O
  }
$ B0 g- i/ D, M) U. G  p->bian_ma=item;
; U7 j  N) |7 q/ s9 Q& e: v7 w, B  p->next=top;
8 N) N' F$ i. }; Q  top=p;4 q( ~1 K+ }* ~7 a7 n
  }
; \: F% u5 o/ p7 r3 H% B5 [  n  else{' N  u9 @) a! s, l+ h
  top=(link)malloc(sizeof(stack_node));
# r/ p8 y6 D! _7 l- n5 S  if(!top){5 K+ |2 Q  g% d* \% U% B
  printf("Memory allocation error!");
9 K: D- D# e  P  return;
1 v5 _1 e" R, Y4 B8 o+ P; W5 f# p  }
' q# }6 x' M! _  top->bian_ma=item;" _' C! z3 S- M2 T0 P; |; Z3 F" a
  top->next=NULL;
$ G& Z( _- M$ q  }3 c( g3 `' }$ |, }1 ~8 [
  }
8 K5 V; B# p5 r. \8 L  void pop(void){# T# j/ h& y0 b1 E1 H
  link p;
5 ~% j  x; w9 p0 Z  p=top;5 f9 m0 a! N4 e+ D! C1 d1 F4 R& E; a% q
  top=top->next;
5 M8 [( A, W. [. r. |$ _  free(p);
, t1 [2 l2 L) G3 g& h, ~( `2 L  [% f" j  }
& r# T, n! o3 c* N3 y5 i! ^  void makenull(void){
% R! t, M4 l" e5 g' a  E  while(top!=NULL)% R) @3 ~( M6 l5 g" J
  pop();
( Q  X  Q( H; b  }
) v* W! X3 k* _$ i0 d8 e+ i* h  int empty(){3 t/ X- s8 Z( |9 c* L8 q" e
  if(top==NULL)6 @3 p' \7 k5 u  J4 D" G  t
  return 1;4 D8 }* d! h& B1 b1 H, W3 C
  else, \5 O# j) {) o+ J3 A* \
  return 0;
# A' S' V8 \0 ^2 P  K  }
1 A( r7 Z: @4 V& W. ]/ M5 k, k  char* tops(void){
1 H1 d. |- D1 h  return (top->bian_ma);
% k6 {: Z% r) U* C  }+ x& G/ P( V: @# L: U. D) B$ J) e5 Q
  void display_stack(link s){ /*显示栈重的内容*/, p5 K! h! d' F1 ~9 p
  link ptr;; Z! O* p$ X/ K  A- b/ v5 H- m
  ptr=s;
! U9 s+ G7 ]6 a9 e8 @7 |  while(ptr!=NULL){
6 ]! e9 q  }4 ~$ q  printf("%s",ptr->bian_ma);" b. N) _) M& C- V6 z- }! @8 n
  ptr=ptr->next;6 d3 p" U) O" Y- A8 a
  }
% B/ }( m$ t3 }- l  }
; @; A  Z4 |9 O. X  /***************************stack__difination is end************************/6 P) g* i; W8 R
  void display(list h){ /*显示链表1*/
* G1 U- S2 X& ^' G- f  w  list ptr;
6 P: H6 C% C  a$ `! w, A  int i=1;
/ W% W0 Q/ P7 ~2 ~$ u- j  ptr=h->next;& S* |" _4 f" a, o# V3 E: X6 `
  while(ptr!=NULL){
# Y- h; I+ q, S1 P  printf("%d,%c,%d\n",i,ptr->data,ptr->count);; i* I1 }  X  j* l. }5 z$ M
  i++;
4 |% e0 v& O' a! S  ptr=ptr->next;/ \2 q% o9 f; W; K- y/ K0 v
  }2 C& s, g1 S9 d8 ]
  }1 m2 B% n! ^. Z4 Q# J0 J# q. t
  void display_b(list_b h){ /*显示链表2*/9 B1 w" t. W( k7 `( V
  list_b ptr;( `% ?5 f& H5 d
  int i=1;
% d  F& k4 d9 I2 r9 d' g  ptr=h->next;
4 L9 R$ B% I5 j" X/ l, G  while(ptr!=NULL){
! X, Y% M( |% B* U! n  printf("%d,%c\n",i,ptr->data);& M- D# D5 M& N  S% R$ ]
  i++;  m- f; E+ e. J6 k
  ptr=ptr->next;) N  h" A% [7 R; P* @* K
  }, Q0 g: z3 ^6 i$ J
  }
2 B! {7 X* O) I5 o  void insert(char item){ /*用于插入元素以建立链表1*/
* Y2 ^) F  D8 c& |5 i  list temp,ptr;0 ?8 H$ p% i! }, |1 B3 I( j5 ]/ q
  int flag;& G0 A* Y2 Z3 \7 [( Q
  ptr=head->next;( [0 y3 M9 s+ e/ w; M
  if(ptr==NULL){- `# v* H7 U$ I1 d# G
  head->next=(list)malloc(sizeof(node));
0 A. _; Z% O. u% u4 g  head->next->data=item;
- t6 T4 }7 Z  f2 p& a/ @# M  head->next->count=1;7 q; V, f8 q. ~6 h' i: s+ N/ n
  head->next->next=NULL;. h( a5 _% A" A0 U6 {) l; h
  }  O  v" n' ]( ~# e# |; I
  else{0 N8 V/ ~/ A! j. A; i
  while(ptr!=NULL){, C% @7 C( l% U" `: x7 j
  if(ptr->data==item){
2 P% Y- t8 D2 y5 D  ptr->count=ptr->count+1;4 [- [" \) O& J6 ]
  flag=1;
' K" f* O* g, X8 R  }
% v" }& I  A. J- P$ F6 o# c7 A$ Z  ptr=ptr->next;
4 R" G; ]1 F6 h  }
) q0 H5 L9 T% g" U  ptr=head;8 F9 T* Z# G4 X
  if(flag==1), o" n" O5 {: D
  return;
+ V+ b* k" d1 H1 ~4 Y  else{  D; Q& l4 e. n
  temp=ptr->next;
0 I4 _$ ]  r# ~* Z2 Y9 ~2 [: r  ptr->next=(list)malloc(sizeof(node));6 v2 S: |& v- ]9 H+ h
  ptr->next->data=item;/ T8 u) {3 ^" S' u, C9 W: L9 y% a
  ptr->next->count=1;/ s( q% ]! i: v6 p
  ptr->next->next=temp;
& k2 c' h( ~9 v8 G  }
6 W2 e. E( a$ e4 p/ D  }
7 m$ X; F6 Z- W8 l  }
' O7 g# _) D/ J. ^
% \- O8 a9 P! B, R4 M/ Y( X9 G  void insert_b(char item){ /*插入元素以建立链表2*/4 n9 G3 x. I5 ~' B3 L( c+ p
  list_b ptr_b, temp_b;( d$ J. Z. d; {: u5 X- c, d2 ]
  ptr_b=head_b;
  u1 k3 ?8 b) w; I  if(ptr_b->next==NULL){
( ]+ v" ]( X. L5 M  head_b->next=(list_b)malloc(sizeof(node_b));! s' _) v" M# O; \* Z4 t
  head_b->next->data=item;0 `- M1 d/ I* d) q
  head_b->next->next=NULL;9 [# z9 G0 l2 E& _- K
  }0 q5 G! h' w6 y- n  h  F+ @6 P
  else{" j' t6 o( U: r. K+ m5 X" t
  while(ptr_b->next!=NULL){& t2 \6 g! s& i- |
  ptr_b=ptr_b->next;8 `  z8 W- h6 s5 Z, ]; r
  }0 A7 \" O" K9 I
  ptr_b->next=(list_b)malloc(sizeof(node_b));% W4 e& T( h9 m, d/ ]7 e. Q2 H  D
  ptr_b->next->data=item;4 h: n# u. j& l, I) s5 S$ A- x
  ptr_b->next->next=NULL;) o% K2 A8 \- u
  }
, r: S: b. t" p% e+ Q. o/ Z* H  }" F7 ?- b. n4 T& Q5 P. x
  void search(void){ /*搜索文件并将文件中的数据分别存入作用不同的链表中*/
. b* W' U1 t9 Q* k9 n" X0 _1 l  FILE *fp;+ \3 c" I2 P; h5 q  E
  list ptr;6 p* S" {+ j* h& h' m! O
  char ch;2 \" U0 |* ]$ C3 k$ \: n$ {
  if((fp=fopen("test.txt","r"))==NULL)9 \9 B. V" {6 j0 P. A+ P' \% @
  printf("Reading error!\n");  ?; n0 p, }6 v4 E7 T4 u# [
  while(!feof(fp)){
4 j9 Z) U9 q4 s& w+ I- d  ch=getc(fp);9 J$ C6 Z0 y  f: i$ V* w
  if(ferror(fp)){  @+ c: j! Z3 q1 {
  printf("error!\n");
" H4 w2 ~5 N- O5 X+ p( n  break;& b1 ]" Q, N& `7 i0 z
  }  A* J) c! C! w2 w  F; `8 {. d
  if(ch==EOF)# d! ?! s7 h/ _: {" o. v7 e
  break;' k  l( T  ?+ ~! O* @5 w
  insert(ch); /*插入元素进链表1*/
回复

使用道具 举报

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

常用算法之哈夫曼算法

  insert_b(ch); /*插入元素进链表2*/; T7 P3 K2 t$ M
  }
# B  g; i- j! |$ G5 |% `1 w$ s  printf("\n");
* ^1 n9 G; M7 N4 V" m% E  fclose(fp);+ j, k! t+ Y# S5 i! w
  }
2 m+ [. {+ w: w( ]( d' Q" S  void display_struct(int n){ /*显示哈夫曼算法中的3个结构树组 */
4 Y! L4 Y8 n' n3 p  int i=0;9 ^% G" K5 [" e# j
  printf("\n\n=======================================\n\n");
0 I) X. o+ l0 k/ {  printf("FOREST_STRUCT_ARRY :\n\n\n");# T' v# i  ]2 s) j* H8 F8 _* U
  for(i=0;inext;
& {  X( r+ W' w  g- U  while(ptr!=NULL){& Z+ }5 H  m" D
  count=ptr->count+count;
6 @: D# n4 V3 g% o5 H/ @% M/ e  n++;
/ K4 I# t4 V, i! M7 k5 d, ~  ptr=ptr->next;% q; f3 W7 ^( H" E: ?
  }</p>  ptr=head->next;
3 |) k) |% Z- e$ W* R0 r5 x% c& ?  forest1=(forest_ptr)malloc(sizeof(forest_node)*n+sizeof(forest_node));
  d$ c; c* e& t$ W: O) w8 g7 q  alphabet1=(alphabet_ptr)malloc(sizeof(alphabet_node)*n+sizeof(alphabet_node));- J1 }- b" v. M* P" |) Y8 K
  tree1=(tree_ptr)malloc(sizeof(tree_node)*n*2-sizeof(tree_node));
- C2 L4 Z2 `; y  ?7 f% ^& L  forest1[0].weight=alphabet1[0].probability=0.0;
4 z& p8 n( H" z/ y% ~% O/ R  forest1[0].root=alphabet1[0].leaf=0;
. A) G1 h8 J% d0 I8 _. R, W2 N  alphabet1[0].symbol='0';
% J4 b7 P4 e' F  f! o- p  while(ptr!=NULL){+ x( o1 _* e: @( y% M
  forest1.weight=alphabet1.probability=ptr->count/count;3 j# Y+ V' k( ^& L
  forest1.root=alphabet1.leaf=i;
( c: `) b" V3 l$ l  alphabet1.symbol=ptr->data;
( C. }. ]" r$ c3 U# b! B7 N  i++;1 s9 o( E% L" C# J7 l. o( a, |
  ptr=ptr->next;+ A  e% e" e  k3 X+ C
  }. r9 X4 s* u  I
  for(i=0;inext;
/ M* S( l3 T3 ]( c  if((fp=fopen("bianma.txt","w"))==NULL)9 U# ?) _: m! h
  printf("Write in a new file error!");
8 o7 \8 ^* H9 x2 @) a3 v  else{8 c" \3 T) [. R5 t* y( g
  while(ptr!=NULL){
" b4 r9 p/ K  S1 X: Y0 C3 I# m  for(i=1;idata==alphabet1.symbol){9 l! Q% o- d  O# i
  strcpy(ch,alphabet1.bianma);# D# b, {  p" p+ |& `2 l' w
  fputs(ch,fp);
3 B1 O0 W, m0 j4 d0 Q& l' W5 ?" P  }
5 z/ Y$ i* L( m* a3 s/ W; H  }
2 I( e5 ?8 Y: k6 A  ptr=ptr->next;
; ?0 }1 ?7 z5 Y  }5 Z" f9 L; k; m: o( t% t% ^) @
  }- l+ D' Y/ {2 g. x' p
  fclose(fp);( j) q( f% T- n% l3 K6 C* Q3 x
  }
+ _" W- R0 e4 u0 Q7 x* W4 f  void main(void){
7 V6 R0 i! D9 Q1 x/ ^% U  int i,num;. q7 T  v) p+ d# h8 v, J3 Z
  char ch;. g8 H9 q6 r& Q5 F1 n0 z
  void huffman(void);
2 O# \) V- n# v- B- O; _4 l& M1 v2 ~. L  void lightones();. X. }$ h( T/ O2 T. x! T9 a+ I+ t0 i
  head=(list)malloc(sizeof(node));. R2 c/ Y1 S/ s+ S! u2 z
  head->next=NULL;! F6 h, @4 L& d
  head->data='\0';
7 f: s6 m7 v7 P2 i- u, w9 s6 s  head->count=0;
% C7 w* `% f* X6 j  head_b=(list_b)malloc(sizeof(node_b));. P2 t! ^% |' A/ |3 i9 @' T3 A
  head_b->data='\0';
( `8 A; T8 t3 |  head_b->next=NULL;+ {# Y3 A2 I' G. P* i- d
  do{  ]# k: u% z' F$ ?/ X& E5 ]+ o
  system("cls");$ o8 G) h' ?: x! R5 I- R8 t
  creat();2 [9 q6 A5 d+ T, A# ?4 X
  search();
- E" Z2 m$ y! a" f; |/ K6 L8 t0 P  printf("\nlianbiao1:\n");
. L$ b) F4 t9 R  display(head);/*显示链表1*/& u" h2 ]/ j* x8 ?$ O! c  [
  getch();
6 e1 S8 n4 k* q# L% Z8 L  printf("\nlianbiao2:\n");9 c2 ~6 Y; h4 u  ]2 X- `
  display_b(head_b);7 ~5 ]3 E0 S, ?
  getch();
) ~& {* _/ R& o7 m9 l3 j2 n; I  num=init_struct();
5 f* t4 E* {5 o( e  printf("\n");: C8 y2 H$ s. @' k% g% D* m
  printf("The 3 init_struct of huffman?\n");  X( d& d* F# M9 Q
  display_struct(num);/*显示初始化的哈夫曼书的相关3个结构数组*/& x) d' d- p4 r- Z. R/ T; e
  lastnode=num;
( o7 T: w) }- A  U: W! L  ]! \2 Z/ J* ~  lasttree=num;  F( u4 K  a1 F+ Y
  huffman();
: L, U; d% }  Y# \  printf("Now the 3 struct through huffman shuanfa\n");
2 w6 Y: S" B$ [# |4 p8 J  display_struct(num);/*显示哈夫曼树中相关的3种结构(经过哈夫曼算法处理)*/
0 \2 \. d  q5 a9 k* Z0 W, y1 v5 c' s  printf("\nThe bian_ma is:\n");
7 e9 Z( P, [4 g0 n( X; v4 C# a  creat_bianma(num);$ V: P+ F# C( f2 H& S+ Q3 N
  write_new_file(num);
$ J: R( W2 j5 ^$ n  printf("\nDo you want to re_try(y/n)?");
) B3 A7 _) @' C2 h+ |  ch=getchar();; N# Z  `. E3 Q
  }while(ch=='y');4 S9 d3 z$ y; D1 Z3 E6 N( b
  }! t$ Q- a! ^( A/ }$ N3 F. X) g/ Y# s
  /*哈夫曼算法-----defination_start*/
$ q. C0 t( c( K* q4 ]  void lightones(void){6 }  h- v9 v0 Z5 l
  int i;
7 ?3 V0 o( e5 x  if(forest1[1].weight1){8 `& D9 v) X3 \5 Z  {* S
  lightones();( z1 S6 {; w# D% g' z
  i=least;
* o& P6 p) W" J" e. q& {/ ]+ P- y0 F& t  j=second;
  H3 X  y! @. r  newroot=creat_tree(i,j);# j$ V# E# |7 Y4 C
  forest1.weight=forest1.weight+forest1[j].weight;4 I& c4 q4 G+ f
  forest1.root=newroot;
  G1 ^1 E8 l6 t" w* i0 v: |  forest1[j]=forest1[lasttree];
( a6 k2 g* ?6 m0 ~' a( H- }  lasttree=lasttree-1;
1 G9 ^/ r2 z! e/ m* }  }
5 J: G, v) O2 i: r  }
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-18 11:11 , Processed in 0.505453 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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