我是靠谱客的博主 踏实花生,最近开发中收集的这篇文章主要介绍SDUTOJ 3345 - 数据结构实验之二叉树六:哈夫曼编码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Problem Description

字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码。该方法完全依据字符出现概率来构造出平均长度最短的编码,称之为最优编码。哈夫曼编码常被用于数据文件压缩中,其压缩率通常在20%~90%之间。你的任务是对从键盘输入的一个字符串求出它的ASCII编码长度和哈夫曼编码长度的比值。

Input

输入数据有多组,每组数据一行,表示要编码的字符串。

Output

对应字符的ASCII编码长度la,huffman编码长度lh和la/lh的值(保留一位小数),数据之间以空格间隔。

Sample Input

AAAAABCD
THE_CAT_IN_THE_HAT

Sample Output

64 13 4.9
144 51 2.8

Hint

Source

xam

思路:使用静态链表组织数据

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct node
{
    char data; // 数据
    int w, l, r, p; // w为权重,l为左孩子,r为右孩子,p为父节点
} tree[100];

int INF = 1e9+7; // 设置最大值

int main()
{
    char str[100];
    int i, j, num, n, m, w1, w2, k1, k2, p, sum, f[100]while(~scanf("%s", str))
    {
        memset(f, 0, sizeof(f)); // 初始化用来检查的f数组
        n = strlen(str);
        m = 0;
        for (i = 0; i < n; i++) // 遍历字符串
        {
            for (j = 0; j < m; j++)
            {
                if (tree[j].data == str[i]) // 若在已初始化的结点中存在该字符,则该节点权值+1
                {
                    tree[j].w++;
                    break;
                }
            }
            if (j == m) // 若已初始化的结点中不存在该字符,则生成一个新的结点
            {
                tree[m].data = str[i];
                tree[m].w = 1;
                tree[m].l = tree[m].r = tree[m].p = -1;
                m++;
            }
        }

        for (i = m; i < 2*m-1; i++) // 将其他结点依次输出
        {
            w1 = w2 = INF; // 初始化为最大值
            k1 = k2 = -1; // 初始化
            for (j = 0; j < i; j++) // 遍历带权结点
            {
                if (f[j]) // 若该结点使用过,则跳过
                {
                    continue;
                }
                if (tree[j].w < w1) // 选择两个权值最小的结点,其中w1比w2小
                {
                    w2 = w1;
                    k2 = k1;
                    w1 = tree[j].w;
                    k1 = j;
                }
                else if (tree[j].w < w2)
                {
                    w2 = tree[j].w;
                    k2 = j;
                }
            }
            // 找到权值最小的两个结点
            f[k1] = f[k2] = 1; // 标记已使用
            // 创建新的结点
            tree[i].w = tree[k1].w + tree[k2].w;
            tree[i].l = k1;
            tree[i].r = k2;
            tree[i].p = -1;
            // 连接三个结点
            tree[k1].p = tree[k2].p = i;
        }
        // 计算
        sum = 0;
        for (i = 0; i < m; i++)
        {
            num = 0;
            p = tree[i].p;
            while(p != -1)
            {
                num++;
                p = tree[p].p;
            }
            sum += num*tree[i].w;
        }
        printf("%d %d %.1fn", n*8, sum, n*8.0/sum);
    }
    return 0;
}

最后

以上就是踏实花生为你收集整理的SDUTOJ 3345 - 数据结构实验之二叉树六:哈夫曼编码的全部内容,希望文章能够帮你解决SDUTOJ 3345 - 数据结构实验之二叉树六:哈夫曼编码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部