哈夫曼树

#include <stdio.h>
#include <stdlib.h>
/*
哈夫曼树:是一个有序查找树.符号左节点<=根节点  右节点<=根节点.与查找树区别主要是所有目标数节点作为树终端节点
哈夫曼树创建之后,可以给每个终端节点产生一个唯一二进制编码(0,1)
如: 终端节点存储值100,如果产生haffman树 生成一个编码值(0011).一般用haffman 编码值用来压缩或加密
构造haffman树,如何产生编码:
1.升序排列节点存储数
2.取最小的两个数作为树的终端节点,并将其和作为根节点
3.把根节点存储的值 放入到升序数组中
4.重复执行2 3 4步骤
左孩子编码为0,右孩子编码为1
从树根节点出发到达终端节点连接成一段二进制编码串
如何评估haffman树最优:
计算树权重值
weight=终端节点存储值*层次数 之和  
权重值最小haffman 树最优
*/
//定义树节点类型
typedef struct tree_node
{
    int data;
    struct tree_node * lchild;
    struct tree_node * rchild;
}tree_node;

//排序
void  sort_array(int *array,int len)
{
    int i,j;
    for(i=0;i<len;i++)
    {
        for(j=0;j<len-i-1;j++)
        {
            if(array[j]>array[j+1])
            {
                int tmp=array[j];
                array[j]=array[j+1];
                array[j+1]=tmp;
            }
        }
    }
}

//构建haffman树
tree_node *  init_haffman_tree(int *array,int len)
{
    sort_array(array,len);
    //定义一个指针数组,指向节点
    tree_node** ptr_array=(tree_node**)malloc(len*sizeof( tree_node*));

    //把待处理树生成节点;
    int i;
    tree_node* ptr_new;
    for(i=0;i<len;i++)
    {
       ptr_new=(tree_node*)malloc(1*sizeof(tree_node));
       ptr_new->data=array[i];
       ptr_new->lchild=NULL;
       ptr_new->rchild=NULL;
       //把节点地址保存到指针数组中
       ptr_array[i]=ptr_new;
       ptr_new=NULL;
    }
    //取指针数组中最小两个元素组成子树,并将子树根节点存入到数组中并保持升序.
    int  index=0;
    while(1)
    {
        //创建子树根节点
        ptr_new=(tree_node*)malloc(1*sizeof(tree_node));
        ptr_new->data=ptr_array[index]->data+ptr_array[index+1]->data;
        ptr_new->lchild=ptr_array[index];
        ptr_new->rchild=ptr_array[index+1];
        ptr_array[index]=NULL;
        ptr_array[index+1]=NULL;

        //子树根节点存入到数组中
        int  j=index+2;
        index++;
        if(index==len-1)
        {
            break;
        }
        while(ptr_new->data>ptr_array[j]->data)
        {
            ptr_array[j-1]=ptr_array[j];
            j++;
            if(j==len)
             break;
        }
        ptr_array[j-1]=ptr_new;   
    }
    return ptr_new;
}

//中序输出haffman树
void  print_mid_haffman_tree(tree_node*  root)
{
    if(root!=NULL)
    {
        print_mid_haffman_tree(root->lchild);
        printf("%d\t",root->data);
        print_mid_haffman_tree(root->rchild);
    }
}

//输出haffman编码
void  get_haffman_code(tree_node *  root,int len)
{
    static int code_array[10];
    if(root->lchild==NULL && root->rchild==NULL)
    {
        printf("%d:",root->data);
        int i;
        for(i=0;i<len;i++)
        {
            printf("%d",code_array[i]);
        }
        printf("\n");
    }
    else
    {
        code_array[len]=0;
        get_haffman_code(root->lchild,len+1);
        code_array[len]=1;
        get_haffman_code(root->rchild,len+1);
    }
}

//haffman 树权重值
int   get_haffman_weight(tree_node* root,int len)
{
    if(root->lchild==NULL && root->rchild==NULL)
    {
        return root->data*len;
    }
    else
    {
        return  get_haffman_weight(root->lchild,len+1)+ get_haffman_weight(root->rchild,len+1);
    }
}

int main(int argc,const char* argv[])
{
    int array[]={35,23,67,12,16,98,68,37,52,71};
    tree_node*  root=init_haffman_tree(array,10);
    print_mid_haffman_tree(root);
    printf("\n");
    get_haffman_code(root,0);
    printf("weight=%d\n",get_haffman_weight(root,0));
    return 0;
}

运行结果:
运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值