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

原创 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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

哈夫曼编码问题再续(下篇)——优先队列求解

上篇描述了哈夫曼编码问题的基本描述以及建造一个哈夫曼树的过程分析,那么当算法已经描述清楚之后,我们要怎么样来实现 代码呢?或者说,给你一些带有权值的叶子节点,要怎么样利用程序快速算出所对应的哈夫曼树...

uva - 10954 - Add All(优先队列、哈夫曼编码思想)

题意:题目名称就是你要做的任务:把一些数加起来。但是这对你来说一定是太简单了,所以让我们加一些东西在里面。 做加法要付出的代价(cost) 定义为这2个数的总和,所以要加1 和10 所需付出的代价为1...

C++优先队列解决哈夫曼(Huffmam)编码问题 (STL priority_queue)

优先队列解决哈夫曼(Huffmam)编码问题 (STL priority_queue)

C++ STL 优先队列 及其 霍夫曼编码应用示例

优先队列(priority queue) 优先队列是一种比较常用的结构,普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。 当访问元素时...

C++ STL 优先队列 及其 霍夫曼编码应用示例

优先队列(priority queue) 优先队列是一种比较常用的结构,普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。 当访问元素时,具有最高优...

poj-3253-sdutoj-2127-哈夫曼树-优先队列

Description Farmer John wants to repair a small length of the fence around the pasture. He measures...

POJ 3253 Fence Repair(优先队列构造哈夫曼树)

割木板,割木板的长度就是花的钱。比如你要8 8 5 的木板,最简单的方式是把21的木板割成13,8,花费21,再把13割成5,8,花费13,共计34,当然也可以先割成16,5的木板,花费21,再把16...

哈夫曼树 --- 优先队列(C++STL)

数据结构实验之二叉树六:哈夫曼编码 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description字符...

[解题报告]POJ 1521 ZOJ 2399 POJ 3253 哈夫曼树,优先队列

这三题都是哈夫曼树的应用,使用了STL中的优先队列 priority_queue,即在每次插入后都会保证队列中的数按优先级有序.关于priority_queuegreater >, 第一个参数为队列中...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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