HuffmanCode.h

 #ifndef HUFFMANCODE_H
 #define HUFFMANCODE_H

 enum LRSTATUS
 {
     LEFTCHILD, //左子树
     RIGHTCHILD //右子树
 };

 struct HuffmanCode
 {
     //哈弗曼编码类
     int weight; //权值
     int * pPath; //路径指针
     int pathLength; //路径长度
     HuffmanCode() //默认构造函数
     {
         weight = ;
         pPath = ;
         pathLength = ;
     }
     //HuffmanCode(int n) //初始化路径指针成员
     //{
     //    pPath = new int [n];
     //}
     //~HuffmanCode() //销毁并释放路径指针成员
     //{
     //    if (0!=pPath)
     //    {
     //        delete [] pPath;
     //        pPath = 0;
     //    }
     //}
 };

 #endif //HUFFMANCODE_H

HuffmanNode.h

 #ifndef HUFFMANNODE_H
 #define HUFFMANNODE_H

 enum NODESTATUS
 {
     IN_FOREST, //在森林中
     OUT_FOREST //不在森林中
 };

 struct HuffmanNode
 {
     //哈弗曼节点结构类
     int weight; //节点权值
     NODESTATUS flag; //是否在森林里的标志:IN_FOREST为在森林中;OUT_FOREST为不在森林中
     HuffmanNode * parent; //双亲指针
     HuffmanNode * lChild; //左子树指针
     HuffmanNode * rChild; //右子树指针

     HuffmanNode() //初始化成员数据
     {
         weight = ;
         flag = OUT_FOREST;
         parent = ;
         lChild = ;
         rChild = ;
     }
 };

 #endif //HUFFMANNODE_H

HuffmanTree.h

 #ifndef HUFFMANTREE_H
 #define HUFFMANTREE_H

 #include "HuffmanCode.h"
 #include "HuffmanNode.h"

 class HuffmanTree
 {
     //哈夫曼树类
 private:
     HuffmanNode * pNode; //哈弗曼节点指针(即哈弗曼树的节点数组)
     HuffmanCode * pCode; //哈弗曼编码指针(即哈弗曼树的路径数组)
     int * pWeight; //哈弗曼权值指针(即哈弗曼树的权值数组)
     int size; //哈弗曼权值数组大小
 protected:
 public:
     HuffmanTree(int * pWeight, int size); //哈夫曼树构造函数
     ~HuffmanTree(){}; //哈弗曼树析构函数

     void CreateHuffmanTree(HuffmanNode ** ppNode); //创建哈弗曼树,使用ppNode返回哈弗曼节点数组
     void GetHuffmanCode(HuffmanNode * pNode, HuffmanCode ** ppCode); //获取哈弗曼编码,使用ppCode返回哈弗曼路径数组
 };

  void FreeHuffmanTree(HuffmanNode ** ppNode); //释放有函数CreateHuffmanTree申请的动态内存
  void FreeHuffmanTree(HuffmanCode ** ppCode); //释放有函数GetHuffmanCode申请的动态内存

 #endif //HUFFMANTREE_H

HuffmanTree.cpp

 #include "HuffmanTree.h"
 #include <iostream>
 #include <iomanip> //for setw()

 using namespace std;

 #define DEBUG

 #define MAX_VALUE 0x7FFFFFFF
 #define WIDTH 12

 //************************************
 // Method:    HuffmanTree
 // FullName:  HuffmanTree::HuffmanTree
 // Access:    public
 // Returns:
 // Qualifier: HuffmanTree类构造函数,使用HuffmanTree类之前必须进行类对象初始化
 // Parameter: int * pWeight
 // Parameter: int size
 //************************************
 HuffmanTree::HuffmanTree(int * pWeight, int size)
 {
     this->pWeight = pWeight;
     this->size = size;
 }

 //************************************
 // Method:    CreateHuffmanTree
 // FullName:  HuffmanTree::CreateHuffmanTree
 // Access:    public
 // Returns:   void
 // Qualifier: 创建哈弗曼树,返回指向保存哈弗曼树节点数组的指针
 // Parameter: HuffmanNode * * ppNode
 //************************************
 void HuffmanTree::CreateHuffmanTree(HuffmanNode ** ppNode)
 {
     _ASSERT(pWeight || ppNode); //判断是否是空指针

     *size-; //哈弗曼树总节点数
     )
         return ; //出现错误退出函数
     pNode = new HuffmanNode [nodeNum];
     _ASSERT(pNode);
      ; i<size ; ++i) //赋初值
     {
         pNode[i].weight = pWeight[i];
         pNode[i].flag = IN_FOREST;
     }
     int min1 = MAX_VALUE, min2 = MAX_VALUE; //最小值和次小值
     , pos2 = -; //最小值和次小值位置
      ; i<size ; ++i) //遍历所有节点并且赋值
     {
          ; j<nodeNum ; ++j) //查找最小值和次小值
         {
             if (pNode[j].flag==IN_FOREST && pNode[j].weight<min1)
             {
                 min2 = min1;
                 pos2 = pos1;
                 min1 = pNode[j].weight;
                 pos1 = j;
             }
             else if (pNode[j].flag==IN_FOREST && pNode[j].weight<min2)
             {
                 min2 = pNode[j].weight;
                 pos2 = j;
             }
         }
         !=pos1 && -!=pos2)
         {
             //生成最小值和次小值的二叉树双亲
             pNode[size+i].weight = (pNode[pos1].weight+pNode[pos2].weight);
             pNode[size+i].flag = IN_FOREST;
             pNode[size+i].lChild = &pNode[pos1];
             pNode[size+i].rChild = &pNode[pos2];
             pNode[pos1].flag = OUT_FOREST;
             pNode[pos1].parent = &pNode[size+i];
             pNode[pos2].flag = OUT_FOREST;
             pNode[pos2].parent = &pNode[size+i];
 #ifdef NODEBUG
             cout << "pNode[" << (size+i) << "].weight = " << pNode[size+i].weight << endl;
             cout << "pNode[" << (size+i) << "].flag = " << pNode[size+i].flag << endl;
             cout << "pNode[" << (size+i) << "].parent = " << pNode[size+i].parent << endl;
             cout << "pNode[" << (size+i) << "].lChild = " << pNode[size+i].lChild << endl;
             cout << "pNode[" << (size+i) << "].rChild = " << pNode[size+i].rChild << endl;
             cout << "pNode[" << (pos1) << "].weight = " << pNode[pos1].weight << endl;
             cout << "pNode[" << (pos1) << "].flag = " << pNode[pos1].flag << endl;
             cout << "pNode[" << (pos1) << "].parent = " << pNode[pos1].parent << endl;
             cout << "pNode[" << (pos1) << "].lChild = " << pNode[pos1].lChild << endl;
             cout << "pNode[" << (pos1) << "].rChild = " << pNode[pos1].rChild << endl;
             cout << "pNode[" << (pos2) << "].weight = " << pNode[pos2].weight << endl;
             cout << "pNode[" << (pos2) << "].flag = " << pNode[pos2].flag << endl;
             cout << "pNode[" << (pos2) << "].parent = " << pNode[pos2].parent << endl;
             cout << "pNode[" << (pos2) << "].lChild = " << pNode[pos2].lChild << endl;
             cout << "pNode[" << (pos2) << "].rChild = " << pNode[pos2].rChild << endl;
 #endif //DEBUG
             //重置最小值和次小值
             min1 = min2 = MAX_VALUE;
             //重置最小值和次小值位置
             pos1 = pos2 = -;
         }
         )
         {
             pNode[size+i-].flag = OUT_FOREST;
         }
 #ifdef NODEBUG
         cout << "node [] = {" << setw(WIDTH) << "weight" << setw(WIDTH) << "flag" << endl;
          ; k<nodeNum ; ++k)
         {
             cout << setw() << " ";
             cout << setw(WIDTH) << (pNode[k].flag== ? "IN_FOREST" : "OUT_FOREST") << setw(WIDTH) << pNode[k].weight << endl;
         }
         cout << setw() << "}" << endl;
 #endif //DEBUG
     }
 #ifdef NODEBUG
      ; k<nodeNum ; ++k)
     {
         cout << "pNode[" << (k) << "].weight = " << pNode[k].weight << endl;
         cout << "pNode[" << (k) << "].flag = " << pNode[k].flag << endl;
         cout << "pNode[" << (k) << "].parent = " << pNode[k].parent << endl;
         cout << "pNode[" << (k) << "].lChild = " << pNode[k].lChild << endl;
         cout << "pNode[" << (k) << "].rChild = " << pNode[k].rChild << endl;
     }
 #endif //DEBUG
     *ppNode = pNode;
 }

 //************************************
 // Method:    GetHuffmanCode
 // FullName:  HuffmanTree::GetHuffmanCode
 // Access:    public
 // Returns:   void
 // Qualifier: 创建哈夫曼编码,返回指向哈弗曼编码数组的指针(注:调用该函数前一定要先使用函数CreateHuffmanTree)
 // Parameter: HuffmanNode * pNode
 // Parameter: HuffmanCode * * ppCode
 //************************************
 void HuffmanTree::GetHuffmanCode(HuffmanNode * pNode, HuffmanCode ** ppCode)
 {
     _ASSERT(pNode || ppCode);
     )
         return ; //终止函数执行
 #ifdef NODEBUG
      ; k<size*- ; ++k)
     {
         cout << "pNode[" << (k) << "].weight = " << pNode[k].weight << endl;
         cout << "pNode[" << (k) << "].flag = " << pNode[k].flag << endl;
         cout << "pNode[" << (k) << "].parent = " << pNode[k].parent << endl;
         cout << "pNode[" << (k) << "].lChild = " << pNode[k].lChild << endl;
         cout << "pNode[" << (k) << "].rChild = " << pNode[k].rChild << endl;
     }
 #endif //DEBUG

     pCode = new HuffmanCode [size];
     _ASSERT(pCode);

      ; i<size ; ++i) //赋值操作
     {
         pCode[i].weight = pWeight[i]; //权值赋值
         ; //临时变量
         HuffmanNode * temp = &pNode[i]; //临时变量
         while (NULL!=temp->parent)
         {
             ++pCode_Length;
             temp = temp->parent;
         }
         pCode[i].pathLength = pCode_Length; //路径长度赋值
         pCode[i].pPath = new int [pCode[i].pathLength]; //路径数组创建
         temp = &pNode[i]; //重新复制临时变量
          ; j>= ; --j) //路径数组赋值
         {
             if (NULL!=temp->parent)
             {
                 HuffmanNode * putValue1 = temp->parent->lChild; //DEBUG
                 HuffmanNode * putValue2 = temp->parent->lChild; //DEBUG
                 if (temp==temp->parent->lChild)
                     pCode[i].pPath[j] = LEFTCHILD;
                 else
                     pCode[i].pPath[j] = RIGHTCHILD;
                 temp = temp->parent;
             }
         }
 #ifdef NODEBUG
         cout << "code [] = {" << setw(WIDTH) << "weight" << setw(WIDTH) << "pPath" << endl;
         cout << setw() << " ";
         cout << setw(WIDTH) << pCode[i].weight << ", ";
         cout << setw() << " ";
          ; k<pCode_Length ; ++k)
             cout << pCode[i].pPath[k] << ",";
         cout << endl;
 #endif //DEBUG
     }
 #ifdef NODEBUG
      ; k<size*- ; ++k)
     {
         cout << "pNode[" << (k) << "].weight = " << pNode[k].weight << endl;
         cout << "pNode[" << (k) << "].flag = " << pNode[k].flag << endl;
         cout << "pNode[" << (k) << "].parent = " << pNode[k].parent << endl;
         cout << "pNode[" << (k) << "].lChild = " << pNode[k].lChild << endl;
         cout << "pNode[" << (k) << "].rChild = " << pNode[k].rChild << endl;
     }
 #endif //DEBUG
     *ppCode = pCode;
 }

 //************************************
 // Method:    FreeHuffmanTree
 // FullName:  FreeHuffmanTree
 // Access:    public
 // Returns:   void
 // Qualifier: 销毁由函数CreateHuffmanTree申请的对象
 // Parameter: HuffmanNode * * ppNode
 //************************************
 void FreeHuffmanTree(HuffmanNode ** ppNode)
 {
     if (NULL!=ppNode && NULL!=*ppNode)
     {
         delete [] *ppNode;
         *ppNode = NULL;
     }
 }

 //************************************
 // Method:    FreeHuffmanTree
 // FullName:  FreeHuffmanTree
 // Access:    public
 // Returns:   void
 // Qualifier: 销毁由函数GetHuffmanCode申请的内存
 // Parameter: HuffmanCode * * ppCode
 //************************************
 void FreeHuffmanTree(HuffmanCode ** ppCode)
 {
     if (NULL!=ppCode && NULL!=*ppCode)
     {
         int size = _msize(*ppCode)/sizeof(HuffmanCode);
          ; i<size ; ++i)
         {
             if (NULL!=(*ppCode+i)->pPath)
             {
                 delete [] (*ppCode+i)->pPath;
                 (*ppCode+i)->pPath = NULL;
             }
         }
         delete [] *ppCode;
         *ppCode = NULL;
     }
 }

Main.cpp

 #include <iostream>
 #include "HuffmanTree.h"

 using namespace std;

 #define DEBUG

 #define _CRTDBG_MAP_ALLOC
 #include <stdlib.h>
 #include <crtdbg.h>

 #ifndef DBG_NEW
 #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
 #define new DBG_NEW
 #endif

 int main() //测试代码
 {
     ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
     ::_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
     ::_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);

     , , , , , , };
     int size = sizeof(weight)/sizeof(int);
 #ifdef DEBUG
     cout << "weight [] = {" ;
      ; i<size ; ++i)
         cout << weight[i] << ", " ;
     cout << "}" << endl;
 #endif //DEBUG
     HuffmanTree obj(weight, size);
     HuffmanNode * pNode = NULL;
     obj.CreateHuffmanTree(&pNode);
     HuffmanCode * pCode = NULL;
     obj.GetHuffmanCode(pNode, &pCode);

     FreeHuffmanTree(&pNode);
     FreeHuffmanTree(&pCode);

     ;
 }

以上程序共5个文件:

1.Main.cpp文件主要实现对哈弗曼树、哈弗曼编码的测试,并且使用VS专用内存泄露检测代码进行内存泄露检测;

2.类HuffmanNode主要实现哈弗曼节点结构构造;

3.类HuffmanCode主要实现对哈弗曼树路径的存储;

4.类HuffmanTree主要实现哈弗曼树,并且实现创建哈弗曼树,创建哈弗曼编码;

5.使用宏#define DEBUG来对哈弗曼类代码中间结果进行验证。

哈弗曼实现(C++)的更多相关文章

  1. C++哈弗曼编码

    // haffman.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using name ...

  2. HDU2527:Safe Or Unsafe(哈弗曼树)

    Problem Description Javac++ 一天在看计算机的书籍的时候,看到了一个有趣的东西!每一串字符都可以被编码成一些数字来储存信息,但是不同的编码方式得到的储存空间是不一样的!并且当 ...

  3. K:哈弗曼树

    相关介绍:  树形结构除了应用于查找和排序等操作时能调高效率,它在信息通讯领域也有着广泛的应用.哈弗曼(Huffman)树就是一种在编码技术方面得到广泛应用的二叉树,它同时也是一种最优二叉树. 哈弗曼 ...

  4. SLT 优先队列 哈弗曼树最小带权路径

    与普通的队列不同,普通的队列是先进先出的,而优先队列出队的顺序不是先进先出,而是大(或者小)元素先出队,需要#include <queue> 成员函数 成员函数 作用 empty() 判断 ...

  5. Safe Or Unsafe(hdu2527)哈弗曼VS优先队列

    Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  6. java实现哈弗曼树

    O(∩_∩)O~~ 概述 我想学过数据结构的小伙伴一定都认识哈弗曼,这位大神发明了大名鼎鼎的“最优二叉树”,为了纪念他呢,我们称之为“哈弗曼树”.哈弗曼树可以用于哈弗曼编码,编码的话学问可就大了,比如 ...

  7. 哈弗曼树的理解和实现(Java)

    哈弗曼树概述 哈弗曼树又称最优树,是一种带权路径长度最短的树,在实际中有广泛的用途.哈弗曼树的定义,涉及路径.路径长度.权等概念.哈弗曼树可以用于哈弗曼编码,用于压缩,用于密码学等. 哈弗曼树的一些定 ...

  8. PKU 1521 Entropy(简单哈弗曼树_水过)

    题目大意:原题链接 给你一个字符串,首先是计算出一个按正常编码的编码长度,其次是计算出一个用霍夫曼编码的编码长度,最后求正常编码的长度除以霍夫曼编码长度的比值,保留一位小数. 解题思路:需要知道 1. ...

  9. POJ 3253 Fence Repair(简单哈弗曼树_水过)

    题目大意:原题链接 锯木板,锯木板的长度就是花费.比如你要锯成长度为8 5 8的木板,最简单的方式是把21的木板割成13,8,花费21,再把13割成5,8,花费13,共计34,当然也可以先割成16,5 ...

随机推荐

  1. 视频 - 在 VirtualBox 中部署 OpenStack

    大家新年好,CloudMan 今天给大家带来一件新年礼物. 一直以来大家都反馈 OpenStack 学习有两大障碍:1. 实验环境难搭2. 体系复杂,难道大今天我就先帮大家解决环境问题.前两天我抽空在 ...

  2. jquery 的datatables插件问题

      翻页后js失效: 重绘事件-当表格重绘完成后 重新绑定事件: draw.dt $('#example').dataTable(); $('#example').on( 'draw.dt', fun ...

  3. NetworkComms V3 之自定义对象

    NetworkComms网络通信框架序言 能够发送自定义对象,并且在发送的时候对发送的对象进行加密,压缩是networkComms v3框架的一个重要特性. 具体可以参考源码中 ExampleCons ...

  4. asp.net中当点击按钮时出现grid编辑弹框

    <dx:ASPxButton runat="server" ID="NewGridButton" Text="新增授权" CssCla ...

  5. 在Jena框架下基于MySQL数据库实现本体的存取操作

    在Jena框架下基于MySQL数据库实现本体的存取操作 转自:http://blog.csdn.net/jtz_mpp/article/details/6224311 最近在做一个基于本体的管理系统. ...

  6. 把数组转换成sql中能使用的字符串

    1.数组对象转换成字符串,拼接成符合sql语句的语法 2.代码如下例子 public static void testString(){        String[] str=new String[ ...

  7. Java SE ---算术运算符

    算术运算符:(加)+,(减)-,(乘)*,(除)/,(求余)%,自增自减 一,算数运算符:当有若干个变量参与运算时,结果类型取决于这些变量中表示范围最大的那个变量类型.如果参加运算的变量中有整型int ...

  8. PHP获取IP地址所在的地理位置

    1.http://ip.qq.com/cgi-bin/searchip?searchip1=XXX 2.http://int.dpool.sina.com.cn/iplookup/iplookup.p ...

  9. Java 8新特性探究(八)精简的JRE详解

    http://www.importnew.com/14926.html     首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 - 导航条 - 首页 所有文章 资讯 ...

  10. 利用VNC远程登录Linux服务器简易版

    我负责管理实验室的一台服务器,安装的系统是CentOS 6.7.使用pietty远程登录服务器(命令行) 需求:使实验室的同学和老师使用RealVNC远程登录服务器. 一,首先检查一下服务器是否安装V ...