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. java 哈夫曼编码

    //哈夫曼树类 public class HaffmanTree { //最大权值 ; int nodeNum ; //叶子结点个数 public HaffmanTree(int n) { this. ...

  5. 哈夫曼(Huffman)编码

    哈夫曼编码(Huffman Coding)是一种非常经典的编码方式,属于可变字长编码(VLC)的一种,通过构造带权路径长度最小的最优二叉树以达到数据压缩的目的.哈弗曼编码实现起来也非常简单,在实际的笔 ...

  6. 哈夫曼树【最优二叉树】【Huffman】

    [转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树:         在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设 ...

  7. 【算法】C语言实现数组的动态分配

    C语言实现数组的动态分配 作者:白宁超 2016年10月27日20:13:13 摘要:数据结构和算法对于编程的意义不言而喻,具有指导意义的.无论从事算法优化方向研究,还是大数据处理,亦或者网站开发AP ...

  8. 架构设计:负载均衡层设计方案(3)——Nginx进阶

    版权声明:欢迎转载,但是看在我辛勤劳动的份上,请注明来源:http://blog.csdn.net/yinwenjie(未经允许严禁用于商业用途!) 目录(?)[-] Nginx继续进阶 1gzip ...

  9. jpeg相关知识

    一.jpeg介绍 JPEG 是 Joint Photographic Exports Group 的英文缩写,中文称之为联合图像专家小组.该小组隶属于 ISO 国际标准化组织,主要负责定制静态数字图像 ...

随机推荐

  1. BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3522  Solved: 1041[Submi ...

  2. matlab画图函数plot()/set/legend

    简单plot()/legend/XY轴范围axis 除了坐标轴信息外还可以添加其它的信息,如所画曲线的信息等:测试代码如下 x=0:pi/20:2*pi; y1=sin(x); y2=cos(x); ...

  3. mybatis一个怪异的问题: Invalid bound statement not found

    ssm中报一下错误: invalid bound statement (not found): me.tspace.pm.dao.userdao.getuser    at org.apache.ib ...

  4. LDAP与jenkins

    1:下载:jenkins.war 2:运行:java -jar jenkins.war  一直让他开着,后者放到后台进程 3:在浏览器输入http://IP:8080   4:设置LDAP     若 ...

  5. 简单总结java 语法

    通过学习慢慢的爱上了这门语言,在Java的学习过程中,可能会遇到形形色色的问题不容易解决,应多去专业论坛了解相关的知识,书本上的知识有限.要会从网上搜索有用的信息加以整理,促进学习的深入和知识水平的提 ...

  6. JavaScript写一个小乌龟推箱子游戏

    推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用 ...

  7. Beta版本冲刺第六天 12.12

    一.站立式会议照片: 二.项目燃尽图: Android端 后台 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 邮箱验证和用户评价的填写 用户评价的查看以 ...

  8. PHP 时间 date,strtotime ,time计算1970开始的第几天

    首先,需要看你的php时区配置参数 方式1:更改php配置文件,然后从其fast-cgi或者php调用的地方: 方式2:date_default_timezone_set('PRC'); date函数 ...

  9. iOS工作笔记(十四)

    1.scrollview的frame指的是其可视范围,contentSize指的是其滚动范围,分别是在水平方向和竖直方向上的 所以要让scrollview在水平方向不能滚动,那么需要如下设置 _scr ...

  10. 解决webApi&lt;Message&gt;An error has occurred.&lt;/Message&gt;不能写多个Get方法的问题

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.     本人最近在研究C#webAPI相关知识,发现webAPI不能够支持 ...