优先队列示例: 哈夫曼编码

原创 2006年05月31日 04:05:00

//  优先队列示例: 哈夫曼编码

//  Modified By Veiz

//  Huffman.h

#ifndef HUFFMAN_H_
#define HUFFMAN_H_

#include <queue>
#include <vector>
#include <string>
#include <istream>
#include <ostream>
#include <fstream>
#include <iostream>

using namespace std;


struct huffmanNode;
typedef huffmanNode* nodePtr;
struct huffmanNode
{   //霍夫曼树结点
    unsigned int freq;   //频率
  
    string code;  //编码
    nodePtr left; 
    nodePtr right;
    nodePtr parent;
};

class Compare
{   //比较类
public:
    bool operator() (const nodePtr& c1, const nodePtr& c2) const
    {
        return  ((*c1).freq > (*c2).freq);
    }
};

class Huffman
{
private:
    static const int MAX_SIZE = 256;
    nodePtr nodePtrArray[MAX_SIZE];
    priority_queue<nodePtr, vector<nodePtr>, Compare> priorityQueue;  //一个优先队列,函数Compare指定了优先准则
    fstream inFile;
    string inFilename;
    string outFilename;
    void CreatePriorityQueue();
    void CreateNodePtrArray();
    void CreateHuffmanTree();
    void CalculateHuffmanCodes();
    void SaveToFile();
public:
    void CreateHuffmanCodes(string inFilename, string outFilename);   
};

#endif /* HUFFMAN_H_ */

 

//  Huffman.cpp

#include "Huffman.h"

void Huffman::CreatePriorityQueue()

    for(int i = 0; i < MAX_SIZE; ++i)
    {
        nodePtrArray[i] = new huffmanNode;
        nodePtrArray[i]->freq = 0;
    }

    CreateNodePtrArray();

    nodePtr entry;
    for(int i = 0; i < MAX_SIZE; ++i)
    {
        entry = nodePtrArray[i];
        if(entry->freq > 0)
        {
            priorityQueue.push(entry);
        } 
    }
}


void Huffman::CreateNodePtrArray()
{
    nodePtr entry;
    inFile.seekg(0, ios::end);
 unsigned int posEnd = inFile.tellg();
 inFile.seekg(0, ios::beg);
    char ch[1];
    for(unsigned int i = 0 ; i < posEnd; ++i)
    {       
        inFile.read(ch, 1);
        entry = nodePtrArray[(unsigned char)(ch[0])];
        ++entry->freq;
        if(entry->freq == 1)
        {   //字符第一次出现
            entry->left = 0;
            entry->right = 0;
            entry->parent = 0;
        }        
    }
}


void Huffman::CreateHuffmanTree()
{
    nodePtr left;  
    nodePtr right; 
    nodePtr sum;

    while(priorityQueue.size() > 1)
    {
        left = priorityQueue.top(); //从优先队列中取出一个子树
        priorityQueue.pop();    //从优先队列中移除一个子树
        left->code = string("0");   //左子树用0表示

        right = priorityQueue.top();    //从优先队列中取出一个子树
        priorityQueue.pop();    //从优先队列中移除一个子树
        right->code = string("1");   //右子树用1表示

        sum = new huffmanNode;
        sum->parent = 0;
        sum->freq = left->freq + right->freq;   //子树根的节点标记等于它两个后代的频率计数之和
        sum->left = left;
        sum->right = right;
        left->parent = sum;
        right->parent = sum;   
        priorityQueue.push(sum);    //把新子树置入优先队列
    }
}

void Huffman::CalculateHuffmanCodes()
{
    string code;
    nodePtr entry;

    for(int i = 0; i < MAX_SIZE; ++i)
    {
        code = "";
        entry = nodePtrArray[i];
        if(entry->freq > 0)
        {
            do
            {
                code = entry->code + code;
                entry = entry->parent;
            }while(entry->parent != 0);
            nodePtrArray[i]->code = code;
        }
    }
}

void Huffman::SaveToFile()
{
    nodePtr entry;
    string line;
    inFile.close();
    ifstream inFile;
    inFile.open(inFilename.c_str(), ios::in | ios::binary);
    ofstream outFile;
    outFile.open(outFilename.c_str(), ios::out | ios::binary);
    if(!outFile)
    {
        cerr << "OutputFileNotFoundException";
    }
    inFile.seekg(0, ios::end);
 unsigned int posEnd = inFile.tellg();
 inFile.seekg(0, ios::beg);
    char ch[1];
    for(unsigned int i = 0 ; i < posEnd; ++i)
    {       
        inFile.read(ch, 1);
        entry = nodePtrArray[(unsigned char)(ch[0])];
        outFile.write(entry->code.c_str(), (streamsize)entry->code.length());
    }
    outFile.close();
}

void Huffman::CreateHuffmanCodes(string inFilename, string outFilename)
{
    this->inFilename = inFilename;
    inFile.open(inFilename.c_str(), ios::in | ios::binary);
    if(!inFile)
    {
        cerr << "InputFileNotFoundException";
    }
    this->outFilename = outFilename;

    CreatePriorityQueue();
    CreateHuffmanTree();   
    CalculateHuffmanCodes();
    SaveToFile();
}

 

 

//  main.cpp

#include <string>
#include <iostream>
#include "Huffman.h"
using namespace std;

int main(int argc, char* argv[])
{
    const string USAGE_MESSAGE = "Usage: HUFFMAN [[drive:][path]inputfilename] [[drive:][path]outputfilename]";
    const string CONTINUE_MESSAGE = "Press any key to continue...";
    if(argc != 3)
    {
        cout << USAGE_MESSAGE << endl;       
    }       
    else
    {
        string inputFilename(argv[1]);
        string outputFilename(argv[2]);
        Huffman huffman;
        huffman.CreateHuffmanCodes(inputFilename, outputFilename);
    }
    cout << CONTINUE_MESSAGE << endl;
    cin.get();
    return 0;
}

简单的Socket示例

【服务器端步骤】 初始化Windows Socket库 创建Socket: socke函数 绑定Socket: bind函数 监听Socket: listen 接受Socket:accept...
  • qq_27991659
  • qq_27991659
  • 2016年05月24日 15:04
  • 542

Jersey基础使用示例

环境配置以及基础服务搭建请参阅:http://blog.csdn.net/u012343179/article/details/73412249 常用的Http方法:Get和Post,可以基本满足日...
  • u012343179
  • u012343179
  • 2017年06月25日 10:26
  • 161

MySQL 官方示例数据库安装

导入文件
  • u011877833
  • u011877833
  • 2014年11月17日 10:41
  • 5871

PL/SQL代码参考示例

PL/SQL代码参考示例 一下的PL/SQL代码为本人在学习PL/SQL时的练习代码,仅供参考。 -----------显示单条id的用户名和相应的年龄,如果不存在则显示‘NO RECORD’----...
  • u012875880
  • u012875880
  • 2013年11月23日 10:36
  • 1205

[01]tensorflow跑示例代码

背景关于 tensorflowTensorFlow™ 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表...
  • SA14023053
  • SA14023053
  • 2016年07月11日 22:01
  • 4124

BCGSoft Demo示例展示之一般示例集合(1/2)

BCGSoft公司的BCGControlBar产品是全球最优秀的MFC界面类库,功能强大,显示丰富,在国际上享有盛誉,并屡次获奖,是VC界面设计的必备首选! 本文中的这些示例程序主要演示了如何创建先进...
  • AABBbaby
  • AABBbaby
  • 2016年04月25日 10:08
  • 573

WSDL文件示例

WSDL文件示例  让我们来研究一下WSDL文件,看看它的结构,以及如何工作。请注意这是一个非常简单的WSDL文档实例。我们的意图只是说明它最显著的特征。以下的内容中包括更加详细的讨论。 ...
  • neubuffer
  • neubuffer
  • 2013年11月23日 14:39
  • 641

【Unity3D】从今天开始做UnityProgrammer!(一)简单浏览官方示例Project

(一)简单浏览官方示例Project
  • xuxcerberus
  • xuxcerberus
  • 2015年08月03日 15:21
  • 923

log4j 的简单示例

在项目的开发过程中,往往需要使用日志的功能,不仅便于调试,更是为了以后问题的排查。本文是一个简单的log4j的示例。...
  • strongyoung88
  • strongyoung88
  • 2017年01月19日 16:10
  • 608

微信小程序「官方示例代码」剖析【下】:运行机制

在上一篇《微信小程序「官方示例代码」浅析【上】》中,我们只是简单的罗列了一下代码,这一篇,让我们来玩点刺激的——就是看看IDE的代码,了解它是怎么运行的。还好微信的开发团队在软件工程的实践还有待提高,...
  • gmszone
  • gmszone
  • 2016年09月22日 23:59
  • 14621
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:优先队列示例: 哈夫曼编码
举报原因:
原因补充:

(最多只允许输入30个字)