数据结构课程设计--哈夫曼树编

#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MAXV 100
//#define MAXVALUE 10000

typedef struct
{
    char data;     //结点的值
 int weight;                  //权值
    int parent,lchild,rchild;    //父节点,左孩子结点,右孩子结点
}HTNode,* HuffmanTree;   //动态分配数组存哈夫曼树
typedef char **HuffmanCode;

 void init(HuffmanTree &HT,int n)
 {     //初始化建立哈弗曼树
  int i;
  char num=0;
  HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));//0号单元未用··从1开始 
  for(i=1;i<2*n;i++)
  {
   HT[i].data=num;
   HT[i].parent=0;
   HT[i].weight=0;
   HT[i].lchild=0;
   HT[i].rchild=0;
  }
  for(i=1;i<n+1;i++)
  {
   getchar();
   printf("输入第%d个结点的值:",i);
   scanf("%c",&HT[i].data);
   printf("对应权值:");
   scanf("%d",&HT[i].weight);
  }
  printf("初始建立成功!");
  printf("\n");
  printf("\n***********初始情况如下***********\n");
  printf("字符值 权值 双亲 左孩子 右孩子\n");
   for(i=1;i<=2*n-1;i++)
   {
    printf("%3c %d  %3d  %5d  %5d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
   }
  printf("*********************************\n");
 }

 void Select(HuffmanTree &HT,int m,int *s1,int *s2)//找到频率最低的两个结点
 {
  int i,min1,min2;
  HT[min1].weight=MAXV;
  HT[min2].weight=MAXV;

  for(i=1;i<=m;i++)
  {
   if(HT[i].parent==0)
   {
    if(HT[i].weight<HT[min1].weight)
    min1=i;
   }
  }
  *s1=min1;

  for(i=1;i<=m;i++)
  {
   if(HT[i].parent==0&&i!=(*s1))
   {
    if(HT[i].weight<HT[min2].weight)
     min2=i;
   }
  }
  *s2=min2;
 }
 //构造哈弗曼树      借用书上代码[数据结构C语言版(严蔚敏 吴伟民)]
 void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int n)
 {
   int i,s1,s2;
   int c,f;
   int start;
   char *cd;
   printf("\n***************哈弗曼树****************\n");
   for(i=n+1;i<=2*n-1;++i) // 建赫夫曼树
   {
    Select(HT,i-1,&s1,&s2);
    HT[s1].parent=HT[s2].parent=i;
    HT[i].lchild=s1;
    HT[i].rchild=s2;
    HT[i].weight=HT[s1].weight+HT[s2].weight;
   }
   printf("字符值 权值 双亲 左孩子 右孩子\n");
   for(i=1;i<=2*n-1;i++)
   {
    printf("%3c %2d  %3d  %5d  %5d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
   }
   printf("*******************************************\n");
   printf("\n");
  
   printf("%d个字符的哈弗曼编码如下:\n",n);
   HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
   cd=(char*)malloc(n*sizeof(char));   
   cd[n-1]='\0';
   for(i=1;i<=n;i++)
   {    
    start=n-1;
    for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
    {// 从叶子到根逆向求编码   
     if(HT[f].lchild==c)
        cd[--start]='0';
     else 
      cd[--start]='1';
    }  
    HC[i]=(char*)malloc((n-start)*sizeof(char));
    strcpy(HC[i],&cd[start]);       //strcpy是字符串复制函数
   }
   free(cd);
   for(i=1;i<=n;i++)
    printf("'%c'编码:%s\n",HT[i].data,HC[i]);
 }

 //哈弗曼树编码  从已经构造的树中取出编码···
 void translateHuffmancode(HuffmanTree &HT,HuffmanCode &HC,int n)
 {
  char str[MAXV],result[MAXV]="\0";
  char temp;
  int i,j;
  getchar();
  printf("\n请输入要编码的字符:");
  gets(str);
  for(i=0;str[i]!='\0';i++)
  { 
   temp=str[i];
   for(j=1;j<=n;j++)
    if(str[i]==HT[j].data)
     strcat(result,HC[j]); //strcat是字符串连接函数
  }
  printf("所求哈夫曼编码为:");
  puts(result);
 }

 //菜单函数
 char  menu()
 {
  char n;
 // system("CLS");                 /*清屏函数  其头文件为“#include<stdlib.h>”*/
  system("color 0A");            /*屏幕和字体颜色控制*/
  printf("欢迎进入系统:\n");
  printf("\t\t\t           哈夫曼编码   \n");
  printf("\t******************************菜单*****************************\n");
  printf("\t***************************************************************\n");
  printf("\t|***********                                       ***********|\n");     
  printf("\t|*******                                                ******|\n");       
  printf("\t|****       1.构造哈弗曼树           2.哈弗曼编码         ****|\n");   
  printf("\t|****                                                     ****|\n");   
  printf("\t|****                      3.退出系统                     ****|\n");   
  printf("\t|****                                                     ****|\n");
  printf("\t|*******                       注:(必须先构建哈弗曼树)******|\n");   
  printf("\t***************************************************************\n");
  printf("\t***************************************************************\n");
  printf("选择1-3:[ ]\b\b");    
  while(1)
  {
   n=getchar();
   if(n<'1'||n>'3')printf("输入错误,请重新输入1-3:[ ]\b\b");
    else
   break;
  }return n;
  }

 //从键盘输入结点个数
 int  dedao()
 { int n;
  printf("初始建立输入结点个数(必须输入数字):");
  scanf("%d",&n);
  return n;
 }

void main()
{   system("color 0A");             //屏幕和字体颜色控制
 int n;
 HuffmanTree HT;                 //代表赫夫曼树
 HuffmanCode HC;           //代表赫夫曼编码

 while(1)
    switch(menu())
 {   case '1':n=dedao();
    init(HT,n); HuffmanCoding(HT,HC,n); break;
  case '2': translateHuffmancode(HT,HC,n); break;
     case '3':printf("谢谢使用,再见!!!\n\n");exit(0);break;
 }
}

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值