哈夫曼图片压缩及解压

哈夫曼图片压缩及解压

文件 功能
Huffman 哈夫曼编码
compress 解压
//Compress.h
#ifndef COMPRESS_H
#define COMPRESS_H
typedef unsigned char * buffer;
int Compress(const char *pFilename);
unsigned char Str2byte(const char *pBinStr);
int Encode(const char*pFilename, const HuffmanCode pHC,buffer &pBuffer, const int nSize);

struct HEAD
{
    char type[4];//文件类型
    int length;//原文件长度
    int weight[256];//权值数值
};
int WriteFile(const char*pFilename, const HEAD sHead, unsigned char * pBuffer, const int nSize);
int InitHead(const char *pFilename, HEAD &sHead);
int UnCompress(const char*pFilename);
#endif
//Huffman.h
#ifndef HUFFMAN_H
#define HUFFMAN_H
#define OK 1
#define SIZE 256
struct HTNode {
    int weight;//权值
    int parent;//父节点
    int lchild;//左孩子
    int rchild;//右孩子
};
typedef HTNode *HuffmanTree;//动态分配数组存储Huffman树
typedef char **HuffmanCode;//动态分配哈夫曼编码表


//void PreorderTraverse(int root, HuffmanTree pHT);
int HuffmanCoding(HuffmanCode &pHC, HuffmanTree &pHT);
int Select(HuffmanTree pHT, int nSize);
void TestHufTree(HuffmanTree pHT);
void TestHufCode(int root, HuffmanTree pHT, HuffmanCode pHC);
void TestHufTreeN(int root, HuffmanTree pHT);

int HfmTree(HuffmanTree &pHT, int *w, int n);

#endif
//huffman.cpp
#include<iostream>
#include<cstring>
#include"huffman.h"
#pragma warning( disable : 4996)
using namespace std;
/*
void PreorderTraverse(int root, HuffmanTree pHT)
{
    cout << pHT[root].weight << " ";//访问节点
    if (pHT[root].lchild)//左孩子
    {
        PreorderTraverse(pHT[root].lchild, pHT);
    }
    if (pHT[root].rchild)//右孩子
    {
        PreorderTraverse(pHT[root].rchild, pHT);
    }
}
*/
int HuffmanCoding(HuffmanCode &pHC, HuffmanTree &pHT)
{
    pHC = (HuffmanCode)malloc((SIZE + 1) * sizeof(char*));
    //无栈非递归遍历 
    char cd[SIZE] = { '\0' };//记录访问路径
    int cdlen = 0;//记录当前路径长度
    for (int i = 1; i < 512; i++)
    {
        pHT[i].weight = 0;//遍历 Huffman树时用作节点的状态标志
    }

    int p = 2*SIZE-1;//根节点
    while (p != 0)
    {
        if (pHT[p].weight == 0)//向左
        {
            pHT[p].weight = 1;
            if (pHT[p].lchild != 0)
            {
                p = pHT[p].lchild;
                cd[cdlen++] = '0';
            }
            else if (pHT[p].rchild == 0)//登记叶子节点的字符编码
            {
                pHC[p] = (char*)malloc((cdlen+1) * sizeof(char));
                cd[cdlen] = '\0';
                strcpy(pHC[p], cd);//复制编码
            }
        }
        else if (pHT[p].weight == 1)//向右
        {
            pHT[p].weight = 2;
            if (pHT[p].rchild != 0)//右孩子为叶子节点
            {
                p = pHT[p].rchild;
                cd[cdlen++] = '1';
            }
        }
        else
        {
            //退回父节点,编码长度减1
            pHT[p].weight = 0;
            p = pHT[p].parent;
            --cdlen;
        }
//      printf("*");
    }
    return 
  • 4
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值