数据结构--我的哈夫曼编译系统

#include 
#include 
#include 
typedef struct node//每个树的节点至少包含3个内容,节点的权值,左子树,右子树的地址
{
    int element;
    char ch;
    char u[100];
    int num;
    struct node *Lchild,*Rchild;
}node;
typedef struct tree
{
   struct node *root;
}tree;//每一棵树都是由一个个节点构成的
tree start;
void Maketree(tree *bt,int x,char c,tree *Lt,tree *Rt)//该函数的目的是传入x的值,建立一棵左子树是Lt,右子树是Rt的树bt(创建方法就是先申请一个空间保存权值,然后记录下左子树右子树的地址,此时注意访问子树有两种方式:
//1直接通过左子树Lt->root来访问2通过p->Lchild来访问,而事实上,我们希望的是第二种方式,即这时左子树已经成为整体的一部分,所以都要清零( Lt->root=Rt->root=NULL;)
{

    node *p=(node*)malloc(sizeof(node));
    p->ch=c;
    p->element=x;
    p->Lchild=Lt->root;
    p->Rchild=Rt->root;
    Lt->root=Rt->root=NULL;
    bt->root=p;//最后把先建立的节点赋值给bt(我们就是通过bt传递的)

}
tree CreatHFMtree(int w[],char s[],int n)//传入两个参数,一个是数组w,一个是节点的数量n
{
    tree zero,h[1000];
    int i,k,k1,k2;
    tree *p;
    p=&zero;
    p->root=NULL;
    for (i=0;i0;k--)//n棵树合并,进行n-1次
    {
    Fmin(h,&k1,&k2,k);//在已经建成的n棵树中,找出最小值的下标k1,次小值得下标k2,最小值每次只会在前k个值(每一次找出两个值都会在数组中忽略最小值)
    Maketree(&h[k1],h[k1].root->element+h[k2].root->element,'#',&h[k1],&h[k2]);//这步可以说是哈夫曼树的核心代码,把找到的两个小值求和h[k1]+h[k2],作为h[k2]的树,而他的子树就是h[k1],h[k2]
    h[k2]=h[k];//每一次把最小值换成队尾的那个,此时最小值就没有了,而有了两个队尾元素,然后由于k--,队尾元素相当于被删除了一个,所以只剩下了除了最小数的全部元素(如果最小值就是队尾元素,那也是成立,可以自己思考一下)
    }
    return h[0];
}
void makecode(node *t)//得出译码(每一个子节点的译码都是从父节点那继承来的)
{
    int i,l;
    if (t==start.root)
    {
        for (i=0;i<100;i++)
        start.root->u[i]='\0';
        start.root->num=0;
    }
   if ((t->Lchild==NULL)&&(t->Rchild==NULL))
   {
       printf("%c:",t->ch);
       for (i=0;inum;i++)
       printf("%c",t->u[i]);
       printf("\n");
       return;
   }
    if (t->Lchild!=NULL)
    {
        for (i=0;inum;i++)
        t->Lchild->u[i]=t->u[i];
        t->Lchild->u[t->num]='0';
        t->Lchild->num=t->num+1;
        makecode(t->Lchild);
      }
    if (t->Rchild!=NULL)
    {
        for (i=0;inum;i++)
        t->Rchild->u[i]=t->u[i];
        t->Rchild->u[t->num]='1';
        t->Rchild->num=t->num+1;
        makecode(t->Rchild);
    }
}
void  translate(node *t,char p[])//翻译,先记录下来,因为不知道是否符合规范
{
    char s[100];
    node *q=t;
    int l,i,k=0,max;
    l=strlen(p);
    for (i=0;iLchild)
        q=q->Lchild;
        else
            printf("请输入正确的字符串\n");
    else
    {
    if (p[i]=='1')
        if (q->Rchild)
        q=q->Rchild;
        else
            printf("请输入正确的字符串\n");
    }
    if ((q->Lchild==NULL)&&(q->Rchild==NULL))
    {
     s[k++]=q->ch;
     max=i;
     q=t;
    }
    }
    if (max!=l-1)
        printf("请输入正确的字符串\n");
    else
    {
        for (i=0;ielementelement)
    {
    *k1=0;
    *k2=1;
    min1=h[0].root->element;
    min2=h[1].root->element;
    }
    else
    {
      *k1=1;
      *k2=0;
      min1=h[1].root->element;
      min2=h[0].root->element;
    }
    for (i=2;i<=k;i++)
    if (h[i].root->elementelement
        *k1=i;
         min2=min1;
         min1=h[i].root->element;
    }
    else
        if (h[i].root->elementelement;//直接更新次小值
    }
}
void PreOrd(node *t)
{

    if (t)
    {
        printf("%d %c  ",t->element,t->ch);
        PreOrd(t->Lchild);
        PreOrd(t->Rchild);
    }
}
void menu()
{
    printf("**********************************************************\n");
    printf("*****欢迎使用B14040312宋宇通的小小哈夫曼编译系统**********\n");
    printf("*********创建新的哈夫曼的编译系统请按1***************\n");
    printf("*********从文件输入待编译的字符串请按2***************\n");
    printf("*********从键盘输入待编译的字符串请按3***************\n");
    printf("*********如果你残忍地想退出本系统请按4*******************\n");
}
  int main()
  {
      FILE *fp;
      int w[1000];
      char s[1000];
      char p[1000];
      char cha;
      int i,n,ok=1;
      fp=fopen("d://1.txt","r");
      menu();
      cha=getchar();
     while(cha!='4')
    {
    switch (cha)
    {
    case '1':
      printf("请输入树节点的个数\n");
      scanf("%d",&n);
      printf("请输入节点(格式为频率 对应的字母)\n");
      for (i=0;i







你可能感兴趣的:(堆的学习笔记)