C 压缩文件程序

C 压缩文件程序,c,algorithm,compression,binary-tree,huffman-code,C,Algorithm,Compression,Binary Tree,Huffman Code,我正试图建立一个压缩文件的程序。 我使用的是哈夫曼算法,我通过视频研究了它: 我试着在比特上使用同样的方法——首先,我试着在小字节上使用: 我取了每个半字节(16个选项),给它一个随机频率,然后我构建了一个二叉树,按照半字节的频率排序,就像视频中一样 我成功地将22K位压缩为18K位,到目前为止,它仍然有效。 然后我在字节(256选项)上尝试了它,但它不起作用-开始时它有13M位,压缩后它有89M位 我有一张图片展示了Nibble示例的二叉树: 还有两个exel文件,用于指定半字节树和字节树的

我正试图建立一个压缩文件的程序。 我使用的是哈夫曼算法,我通过视频研究了它:

我试着在比特上使用同样的方法——首先,我试着在小字节上使用: 我取了每个半字节(16个选项),给它一个随机频率,然后我构建了一个二叉树,按照半字节的频率排序,就像视频中一样

我成功地将22K位压缩为18K位,到目前为止,它仍然有效。 然后我在字节(256选项)上尝试了它,但它不起作用-开始时它有13M位,压缩后它有89M位

我有一张图片展示了Nibble示例的二叉树:

还有两个exel文件,用于指定半字节树和字节树的计算:

  • 蚕食:
  • 字节:
我用C语言实现了算法,这里是部分函数:

typedef struct INFO
{
    unsigned char binary;   //Binary number
    int amount; //Frequency
} INFO;

typedef struct TREE
{
    INFO info;
    struct TREE *prev;
    struct TREE *left;
    struct TREE *right;
} TREE;



/** Function that allocates memory and creates a tree node and initializes it */
TREE * treeNodeMalloc()
{
    TREE *p;
    p = (TREE *)malloc(sizeof(TREE));
    if (!p)
        return NULL;
    p->prev = p->left = p->right = NULL;
    return p;
}


/** Function that builds the first sub-root node consist of two binary numbers */
TREE * firstNode(INFO first, INFO second)
{
    TREE *head, *p;
    int i;
    head = treeNodeMalloc();
    if (!head) return 0;
    for (i = 1; i <= 2; i++)
    {
        p = treeNodeMalloc();
        if (!p) { freeTree(head); return 0; }
        p->prev = head;
        if (i % 2)
        {
            p->info.amount = first.amount;
            p->info.binary = first.binary;
            head->left = p;
        }
        else
        {
            p->info.amount = second.amount;
            p->info.binary = second.binary;
            head->right = p;
        }
    }
    head->info.amount = head->left->info.amount + head->right->info.amount;
    return head;
}


/** Function that builds a sub-root node that consist of a node of binary number and a sub-root of two previous binary numbers */
TREE * continuanceNode(TREE *p1, INFO info)
{
    TREE *h, *p2;
    h = treeNodeMalloc();
    if (!h) { freeTree(p1); return 0; }
    p2 = treeNodeMalloc();
    if (!p2) { free(h); freeTree(p1); return 0; }
    p2->info.amount = info.amount;
    p2->info.binary = info.binary;
    p1->prev = p2->prev = h;
    h->left = p1;
    h->right = p2;
    h->info.amount = h->left->info.amount + h->right->info.amount;
    return h;
}


/** Function that builds the last node of the tree - the main root */
TREE * LastNode(TREE *p1, TREE *p2)
{
    TREE *p3;
    p3 = treeNodeMalloc();
    if (!p3)
    {
        freeTree(p1);
        freeTree(p2);
        return NULL;
    }
    p3->left = p1;
    p3->right = p2;
    p1->prev = p2->prev = p3;
    p3->info.amount = p3->left->info.amount + p3->right->info.amount;
    return p3;
}



/** Function that builds the binary tree from the array of INFO (binary numbers and their frequencies),
The function builds the tree from bottum to the top (reverse build) */
TREE * dataToTree(INFO arr[], int size)
{
    int i;
    TREE *h, *p, *t=NULL;
    p = firstNode(arr[0], arr[1]);
    if (!p) return 0;
    for (i = 2; i < size; i++)
    {
        if (p->info.amount > arr[size - 1].amount)
            if (!t)
            {
                t = firstNode(arr[i], arr[i + 1]); 
                i++;
                if (!t) { freeTree(p); return NULL; }
            }
            else
                if (p->info.amount < t->info.amount)
                {
                    p = continuanceNode(p, arr[i]);
                    if (!p) { freeTree(t); return 0; }
                }
                else
                {
                    t = continuanceNode(t, arr[i]);
                    if (!t) { freeTree(p); return 0; }
                }
        else
        {
            p = continuanceNode(p, arr[i]);
            if (!p) { freeTree(t); return 0; }
        }
    }
    h = LastNode(p, t);
    return h;
}
typedef结构信息
{
无符号字符二进制;//二进制数
int amount;//频率
}信息;
类型定义结构树
{
信息;
结构树*prev;
结构树*左;
结构树*右;
}树木;
/**函数,用于分配内存、创建树节点并对其进行初始化*/
TREE*treeNodeMalloc()
{
树*p;
p=(树*)malloc(树的大小);
如果(!p)
返回NULL;
p->prev=p->left=p->right=NULL;
返回p;
}
/**构建第一个子根节点的函数由两个二进制数组成*/
树*第一个节点(信息第一,信息第二)
{
树*头,*p;
int i;
头部=树状软骨();
如果(!head)返回0;
对于(i=1;i-prev=head;
如果(i%2)
{
p->info.amount=first.amount;
p->info.binary=first.binary;
头部->左侧=p;
}
其他的
{
p->info.amount=second.amount;
p->info.binary=second.binary;
头部->右侧=p;
}
}
表头->信息金额=表头->左侧->信息金额+表头->右侧->信息金额;
回流头;
}
/**函数,该函数构建一个子根节点,该子根节点由一个二进制数的节点和前两个二进制数的子根组成*/
树*continuanceNode(树*p1,信息)
{
树*h,*p2;
h=树状软骨();
如果(!h){freeTree(p1);返回0;}
p2=树状软骨();
如果(!p2){free(h);freeTree(p1);返回0;}
p2->info.amount=info.amount;
p2->info.binary=info.binary;
p1->prev=p2->prev=h;
h->左=p1;
h->右=p2;
h->info.amount=h->left->info.amount+h->right->info.amount;
返回h;
}
/**构建树的最后一个节点(主根)的函数*/
树*LastNode(树*p1,树*p2)
{
树*p3;
p3=树状软骨();
如果(!p3)
{
freeTree(p1);
freeTree(p2);
返回NULL;
}
p3->左=p1;
p3->右=p2;
p1->prev=p2->prev=p3;
p3->info.amount=p3->left->info.amount+p3->right->info.amount;
返回p3;
}
/**函数,该函数从信息数组(二进制数及其频率)构建二叉树,
函数从底部到顶部构建树(反向构建)*/
树*dataToTree(信息arr[],整数大小)
{
int i;
树*h,*p,*t=NULL;
p=firstNode(arr[0],arr[1]);
如果(!p)返回0;
对于(i=2;iinfo.amount>arr[size-1].amount)
如果(!t)
{
t=firstNode(arr[i],arr[i+1]);
i++;
if(!t){freeTree(p);返回NULL;}
}
其他的
如果(p->info.amountinfo.amount)
{
p=连续节点(p,arr[i]);
如果(!p){freeTree(t);返回0;}
}
其他的
{
t=连续节点(t,arr[i]);
如果(!t){freeTree(p);返回0;}
}
其他的
{
p=连续节点(p,arr[i]);
如果(!p){freeTree(t);返回0;}
}
}
h=最后一个节点(p,t);
返回h;
}
每个人都说哈夫曼算法是压缩文件的最佳算法,那么我在这里遗漏了什么呢?
我在做什么?

您构建的哈夫曼树是错误的。在每一步中,您都需要融合所有可用根节点中频率最低的两个节点。因此,首先融合9和14,这将为您提供:

  21
 /  \
9   14
下一步是保险丝21和20

    41
   /  \
  21  20
 /  \
9   14
然后是41和50

      91
     /  \
    41  50
   /  \
  21  20
 /  \
9   14
但在这一步中,最低的两个是70和80,所以将它们分别熔断

      91     150
     /  \   /  \
    41  50 70  80
   /  \
  21  20
 /  \
9   14
然后你要把最低的两个,91和100等熔合在一起

然后,树将更加“平衡”,结果可能会更好


你应该知道(从编码理论)有些文本无法压缩。对于给定的压缩算法,总是至少存在一个无法压缩的文本。一般来说,无论您尝试使用什么算法,都至少存在一个无法压缩的文本。所有这些都需要更多的理论解释,但这大致是理论所能说的。

e看看你是否能把你的代码减少到最小长度-。恐怕它已经很小了-完整的代码很长,我只添加了相关的函数和结构。代码完全按照我想要的方式工作,并实现了我“看到”的算法它,我只是想也许你会要求它。我想问题在于我如何使用比特算法,(我如何“看到”它)
每个人都说哈夫曼算法最适合压缩文件
谁和在什么环境下?看一下。我还没有了解算法的复杂性,现在我正在尝试实现它,如果你问谁让我使用它,我已经做了一项研究,当我需要寻找最好、舒适的压缩算法时非常感谢你,我将尝试根据你的构造重建树,然后返回