不知道为什么,我写的代码都是又臭又长。

直接上代码:

#include <iostream>
#include <cstdarg>
using namespace std;
class Node{
public:int weight;int parent, lChildren, rChildren;Node(int weight, int parent, int lChildren, int rChildren):weight(weight), parent(parent), lChildren(lChildren), rChildren(rChildren){}void printNode(){cout<<"weight = "<<weight<<", ";cout<<"parent = "<<parent<<", ";cout<<"lChildren = "<<lChildren<<", ";cout<<"rChildren = "<<rChildren<<endl;}
};class Tree{Node **nodes;char** huffmanCodec;int length,rPos;int mNum;/**给Tree实例增加Node。***/void addNode(Node *node){if(!node){cout<<"addNode中,指针为NULL"<<endl;return;}for(int i = 0; i < length; i++){if(node == nodes[i])//如果存在了就不必加到里面了。。return;}nodes[length++] = node;}/**从数组array中找到最小的两个数值,赋给v1和v2***/void findSmallest2ValueInArray(int *array, int length, int *v1, int *v2, int *v1Pos, int *v2Pos){int t = 0;for(int i = 0; i < length; i++){if(array[i] < 0)continue;++t;if(t == 1){*v1 = array[i];*v1Pos = i;}else if (t == 2){*v2 = array[i];*v2Pos = i;}else{if(*v1 > array[i]){if(*v1 < *v2){*v2 = *v1;*v2Pos = *v1Pos;}*v1 = array[i];*v1Pos = i;}else if(*v2 > array[i]){*v2 = array[i];*v2Pos = i;}}}}/***从当前Tree中找到给定node的下标。生成huffman编码用的。***/int findNodePosViaNode(Node *node){for(int i = 0; i < length; i++){if(nodes[i] == node){return i;}}return -1;}/***从当前Tree中找到给定Weight的node的下标, 并且该node没有parent。生成树结构用的。***/int findNodePosViaWeight(int value, bool isForParent, bool isTheSameWeightNode){for(int i = 0; i < length; i++){if(nodes[i]->parent == -1 && nodes[i]->weight == value && !isForParent && !isTheSameWeightNode){return i;}}return -1;}/***从头至尾找到叶子结点。***/int findHuffmanNodePos(){static int mark;//默认初始化为0for(int i = mark; i < length; i++){if(nodes[i]->lChildren == -1 && nodes[i]->rChildren == -1){mark = i + 1;return i;}}return -1;}/***初始化node***/Node* getNode(Node *node, int value, int parent, int lChildren, int rChildren, bool isForParent, bool isTheSameWeightNode){//最后一个参数,解决这种情况,如果v1是20,//并且v1已经在树中了,然后v2也是20.//这时候要求v2要new一个新的节点。if(node){cout<<"getNode中,指针未初始化为NULL"<<endl;return NULL;}int pos = findNodePosViaWeight(value, isForParent, isTheSameWeightNode);if(pos != -1){node = nodes[pos];}else{node = new Node(value, parent, lChildren, rChildren);}return node;}/***把一个数组初始化为全是-1的数组。***/void initArray2Zero(int *array, int length){for(int i = 0; i < length; i++){array[i] = -1;}}/***打印一个int数组*/void printIntArray(int *array, int length){cout<<"[";for(int i = 0; i < length - 1; i++){cout<<array[i]<<", ";}cout<<array[length - 1]<<"]"<<endl;}/***for debug*/void debug(int i){cout<<"debug "<<i<<endl;}/***根据huffman树生成huffman编码。*/char** generateHuffmanCodec(int num){int topIndex = 0;huffmanCodec = new char*[num];//分配空间for(int i = 0; i < num; i++){int index = 0;char *data = new char[num + 1];//每一个节点的存储单位int thisPos = findHuffmanNodePos();Node *currentNode = nodes[thisPos];while(currentNode->parent != -1){Node *currentParent = nodes[currentNode->parent];if(thisPos == currentParent->lChildren){//0data[index++] = '0';}else if(thisPos == currentParent->rChildren){//1data[index++] = '1';}else{//X, never in.data[index++] = 'X';}thisPos = currentNode->parent;currentNode = currentParent;}data[index] = '\0';huffmanCodec[topIndex++] = data;}return huffmanCodec;}public:/***创造一棵树。***/void makeTree(int num, ...){int weightArray[num];initArray2Zero(weightArray, num);va_list list;va_start(list, num);for(int i = 0; i < num; i++){weightArray[i] = va_arg(list, int);}va_end(list);printIntArray(weightArray, num);//debugint debug_x = 100;while(true){int v1 = -1, v2 = -1, v1Pos = -1, v2Pos = -1;findSmallest2ValueInArray(weightArray, num, &v1, &v2, &v1Pos, &v2Pos);if(v1 == -1 || v2 == -1){cout<<"v1或v2至少有一个是-1, 没被赋值"<<endl;break;}Node *node1 = NULL;node1 = getNode(node1, v1, -1, -1, -1, false, false);addNode(node1);//如果已经存在就不必add。Node *node2 = NULL;node2 = getNode(node2, v2, -1, -1, -1, false, v1 == v2);//万一v1和v2相等,如果不加这个force,那么本来有2个权值相等的节点,就会少添加到树中一个。addNode(node2);Node *parent = NULL;parent = getNode(parent, v1 + v2, -1, -1, -1, true, false);//最后这个参数,在于判断是否是寻找的是parent。如果是parent,那么就算树中已经存在了相同节点,但是也要new一个新节点。//因为树中的节点不是已经有了孩子 就是叶子节点了。都不能做parent了,所以要重新生成。addNode(parent);node1->parent = findNodePosViaNode(parent);node2->parent = node1->parent;parent->lChildren = findNodePosViaNode(node1);parent->rChildren = findNodePosViaNode(node2);weightArray[v1Pos] = -1;weightArray[v2Pos] = v1 + v2;printIntArray(weightArray, num);//debug}mNum = num;generateHuffmanCodec(num);        }/***打印huffman树***/void printTree(){for(int i = 0; i < length; i++){cout<<"pos = "<<i<<", ";nodes[i]->printNode();//cout<<findHuffmanNodePos()<<endl;}}/***打印哈夫曼编码*/void printHuffman(){cout<<"------huffman codec begin-----\n";for(int i = 0; i < mNum; i++){cout<<huffmanCodec[i]<<endl;}cout<<"------huffman codec end-----\n";}/***构造函数与析构函数*/Tree(): nodes(new Node*[100]), huffmanCodec(NULL), length(0), rPos(-1), mNum(0){//为何是int呢?因为我想数组中存储的是Node*,是一个指针,指针应该可以用int来存储。}~Tree(){cout<<"析构"<<endl;delete []nodes;if(huffmanCodec) delete []huffmanCodec;}
};int main(){Tree *tree = new Tree;tree->makeTree(8, 5, 29, 7, 8, 14, 23, 3, 11);tree->printTree();tree->printHuffman();delete tree;
}

书上的例子才30行代码,我写了300行,为什么会这样呢,挺奇怪的,估计还是修炼不够。得努力!

huffman树和huffman编码相关推荐

  1. 数据结构实验三:Huffman树及Huffman编码的算法实现

    Exp03 Huffman树及Huffman编码的算法实现 Author: Maskros 实验目的 了解该树的应用实例,熟悉掌握Huffman树的构造方法及Huffman编码的应用, 了解Huffm ...

  2. 利用Huffman树进行文本编码解码的实现

    --------------------------------- 功能:利用Huffman树进行文本编码解码的实现 环境:WinXP,VC6.0 输入:C:\\in.txt 输出:C:\\out.d ...

  3. Huffman树与Huffman编码

    Huffman树与Huffman编码 问题描述 已知某系统在通信联络中只可能出现6种字符,其使用频度如下表所示: 根据Huffman编码原理,为6种字符设计一种Huffman编码方案. 算法分析与设计 ...

  4. [源码和文档分享]C语言实现的基于Huffman哈夫曼编码的数据压缩与解压缩

    一.实验题目 用哈夫曼编码实现文件压缩 二.实验目的 了解文件的概念 掌握线性链表的插入.删除等算法 掌握Huffman树的概念及构造方法 掌握二叉树的存储结构及遍历算法 利用Huffman树及Huf ...

  5. Huffman树压缩和解压文件

    Huffman树 Huffman树:以静态三叉链的存储结构建立的二叉树 Huffman树是一个带权路径长度最小的二叉树,又称最优二叉树 Huffman树的构造方法 ①将每个结点都看作是一个树: ②选择 ...

  6. 数据结构入门----赫夫曼Huffman树及其应用

    最优二叉树(霍.赫.哈夫曼树) 路    径: 由一结点到另一结点间的分支所构成. 路径长度: 路径上的分支数目.a→e的路径长度=2 树的路径长度: 从树根到每一结点的路径长度之和.树长度=10 带 ...

  7. Huffman树的原理以及代码构建

    我们的目标认识只是基础,代码实现是才是核心 1.Huffman树的定义: 从树中一个结点到另一个结点的之间的分支构成两个结点之间的路径,路径上的分支数称为路径长度.那么树的路径长度就是从树根到每一个结 ...

  8. Fibonacci数列 Huffman树

    Fibonacci数列 for k = 1:6k = int16(k);fprintf('f%d = %d\n', k, Fibonacci(k)); endfunction fk = Fibonac ...

  9. 基于Huffman树的文件压缩(详细)

    文件压缩 开发平台:Visual Studio 2008 开发技术:哈夫曼树,堆排序 项目流程: (1)统计要压缩的文件中各字符出现的次数,利用数据结构中的小堆来构建Huffman树,每次在堆顶选出两 ...

最新文章

  1. Soft robotics:造仿生昆虫机器人柔性骨骼新技术,只需2小时,成本不到7块!
  2. 参数(parameter)和属性(attribute)的区别
  3. java工程师考试题目_成功拿到Offer,Java工程师笔试题及答案!
  4. 鼠标滚轮(mousewheel)和DOMMouseScroll事件 (转载)
  5. 技术揭秘之详解回收站删除文件恢复
  6. CF704B. Ant Man
  7. php 对象赋值后改变成员变量影响赋值对象
  8. MAC 设置$PATH 关闭terminal后就失效 解决方案
  9. 深入理解分布式系统原理与设计
  10. android 充电模式deamon_Android MarsDaemon实现进程及Service常驻
  11. Java跨域问题以及如何使用Cors解决前后端 分离部署项目所遇到的跨域问题
  12. Ruby File.open 方法打开文件和File.new 方法打开文件的差别
  13. python内置函数返回元素个数_Python内置函数
  14. 有效提高工作效率的方法
  15. 图片怎么转jpg?教你两个超简单的图片转jpg格式的方法
  16. Shiro实现logout操作
  17. 一、SpringCloud入门
  18. Kibana快速上手
  19. 记录:macbook 下剪切快捷键
  20. 获得Flash Build Betal2 的注册码

热门文章

  1. 16-acrobat por 简单使用指南
  2. h5打开App的方法。
  3. Python字典部分源码分析,字典是无序的
  4. javascript 利用 - 枚举思想 - 添加地名的一个小例子
  5. [转] 理解RESTful架构
  6. Android常见错误
  7. WinRM设置信任主机
  8. NDKJNI Android 相关资料整理(四)
  9. Cassandra安装测试
  10. Linux下的ATT语法(即GNU as 汇编语法)入门