二叉树&哈夫曼编码

将字符串BADCADFEED进行二进制编码, 哈夫曼编码能减少原始编码的大小

A            二进制   27

A - ‘A’     000      27%占比

对占比进行排序

排序

int weight[] = {5, 8, 15, 15,27,30};

创建哈夫曼树

哈夫曼树

占比 中找出2个最小值  x1 -> 左子树, 第二小值 x2 -> 右子树,   x1 + x2 -> 父结点, 

       x1 + x2

x1                 x2

ABCDEF 作为叶子结点

是一个满二叉树

顺序结构储存哈夫曼树

HaffNode 结点结构体

typedef struct HaffNode{

    int weight;

    int flag;

    int parent;

    int leftChild;

    int rightChild;

} HaffNode;

储存数组 个数2*n-1,满二叉树 

HaffNode *myHaffTree =malloc(sizeof(HaffNode)* (2*n-1));

void Haffman(int weight[],int n,HaffNode *haffTree){

    int j,m1,m2,x1,x2;

    //1.哈夫曼树初始化

    //n个叶子结点. 2n-1

    for(int i =0; i <2*n-1;i++){

        if(I < n)

            haffTree[i].weight= weight[i];

        else

            haffTree[i].weight=0;

        haffTree[i].parent=0;

        haffTree[i].flag=0;

        haffTree[i].leftChild= -1;

        haffTree[i].rightChild= -1;

    }


    //2.构造哈夫曼树haffTree的n-1个非叶结点

    for(int i =0; i< n -1; i++){

         m1 = m2 = MaxValue;

         x1 = x2 =0;

        //2,4,5,7

        for(j =0; j< n + i; j++)//循环找出所有权重中,最小的二个值--morgan

        {

            if(haffTree[j].weight< m1 && haffTree[j].flag==0)

            {

                m2 = m1;

                x2 = x1;

                m1 = haffTree[j].weight;

                x1 = j;

            }else if (haffTree[j].weight< m2 && haffTree[j].flag==0)

            {

                m2 = haffTree[j].weight;

                x2 = j;

            }

        }


        //3.将找出的两棵权值最小的子树合并为一棵子树

        haffTree[x1].parent= n + i;

        haffTree[x2].parent= n + i;

        //将2个结点的flag 标记为1,表示已经加入到哈夫曼树中

        haffTree[x1].flag=1;

        haffTree[x2].flag=1;

        //修改n+i结点的权值

        haffTree[n + i].weight= haffTree[x1].weight+ haffTree[x2].weight;

        //修改n+i的左右孩子的值

        haffTree[n + i].leftChild= x1;

        haffTree[n + i].rightChild= x2;

    }

}

哈夫曼树编码

哈夫曼树编码

E 11  F 1000

编码大小对比

void HaffmanCode(HaffNode haffTree[],int n,Codehaff Code[])

{

    //1.创建一个结点cd

    Code*cd = (Code* )malloc(sizeof(Code));

    intchild, parent;

    //2.求n个叶结点的哈夫曼编码

    for(inti =0; i

    {

        //从0开始计数

        cd->start=0;

        //取得编码对应权值的字符

        cd->weight= haffTree[i].weight;

        //当叶子结点i 为孩子结点.

        child = i;

        //找到child 的双亲结点;

        parent = haffTree[child].parent;

        //由叶结点向上直到根结点

        while(parent !=0)

        {

            if(haffTree[parent].leftChild== child)

                cd->bit[cd->start] =0;//左孩子结点编码0

            else

                cd->bit[cd->start] =1;//右孩子结点编码1

            //编码自增

            cd->start++;

            //当前双亲结点成为孩子结点

            child = parent;

            //找到双亲结点

            parent = haffTree[child].parent;

        }


         int temp =0;

        for(int j = cd->start-1; j >=0; j--){

            temp = cd->start-j-1;

            haffCode[i].bit[temp] = cd->bit[j];

        }


        //把cd中的数据赋值到haffCode[i]中.

        //保存好haffCode 的起始位以及权值;

        haffCode[i].start= cd->start;

        //保存编码对应的权值

        haffCode[i].weight= cd->weight;

    }

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容