0. 序

  • 本以为用最小堆实现个哈夫曼树是个简单的事情,结果一不小心就花了好几个小时才写完。。。实现过程中主要有三个方面的问题没注意,导致花了很多时间进行调试。

    • 一是多重指针malloc分配时要多加注意;
    • 二是指针一定要记得初始化,默认不一定为NULL;
    • 三是结构体赋值问题。
  • 其余的边界问题小心就好了。。另,由于本人水平有限,如有任何问题,欢迎指出解决,谢谢大家!详细结果如下:

1. 哈夫曼树结构定义如下:

// 定义哈夫曼树结构
struct TreeNode {int weight;TreeNode* lChild;TreeNode* rChild;
};

2. 最小堆结构定义如下:

// 定义最小堆结构
struct MinHeap {TreeNode* p;    // 指向存储元素的数组int size;       // 当前元素个数int capacity;   // 最大容量
};

3. 基本操作函数如下:

  • MinHeap* createMinHeap(int capacity); // 创建最小堆
  • bool isFull(MinHeap* minHeap); // 判断最小堆是否已满)
  • void printMinHeap(MinHeap* minHeap); // 遍历最小堆元素
  • void insertMinHeap(MinHeap* minHeap, TreeNode* node); // 插入元素
  • void minHeapAdjust(MinHeap* minHeap, int parent); // 最小堆调整
  • void buildMinHeap(MinHeap* minHeap); // 调整法建立最小堆(n)
  • bool isEmpty(MinHeap* minHeap); // 判断最小堆是否为空
  • TreeNode* deleteMin(MinHeap* minHeap); // 删除最小元素并返回
  • void preOrderTraverse(TreeNode* head); // 先序遍历(递归)
  • TreeNode* buildHuffmanTree(MinHeap* minHeap); // 构造哈夫曼树

4. 具体代码实现如下:

#include <iostream>using namespace std;#define MinData -100000
#define SIZE 10// 定义哈夫曼树结构
struct TreeNode {int weight;TreeNode* lChild;TreeNode* rChild;
};// 定义最小堆结构
struct MinHeap {TreeNode* p;    // 指向存储元素的数组int size;       // 当前元素个数int capacity;   // 最大容量
};// 创建最小堆
MinHeap* createMinHeap(int capacity) {MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));minHeap->p = (TreeNode*)malloc((capacity + 1)* sizeof(TreeNode));minHeap->size = 0;minHeap->capacity = capacity;minHeap->p[0].weight = MinData;minHeap->p[0].lChild = NULL;minHeap->p[0].rChild = NULL;return minHeap;
}// 判断最小堆是否已满
bool isFull(MinHeap* minHeap) {if (minHeap->size == minHeap->capacity) {return true;}return false;
}// 遍历最小堆元素
void printMinHeap(MinHeap* minHeap) {if (minHeap == NULL) {cout << "The min heap is not created." << endl;return;}for (int i = 0; i < minHeap->size; i++) {cout << minHeap->p[i + 1].weight << " ";}cout << endl;
}// 插入元素
void insertMinHeap(MinHeap* minHeap, TreeNode* node) {if (minHeap == NULL) {cout << "The min heap is not created." << endl;return;}if (isFull(minHeap)) {cout << "The min heap is full." << endl;return;}int i = ++(minHeap->size);for (; minHeap->p[i / 2].weight > node->weight; i /= 2) {minHeap->p[i].weight = minHeap->p[i / 2].weight;minHeap->p[i].lChild = minHeap->p[i / 2].lChild;minHeap->p[i].rChild = minHeap->p[i / 2].rChild;}minHeap->p[i].weight = node->weight;minHeap->p[i].lChild = node->lChild;minHeap->p[i].rChild = node->rChild;
}// 最小堆调整
void minHeapAdjust(MinHeap* minHeap, int parent) {int temp = minHeap->p[parent].weight;int child = 0;for (; parent * 2 <= minHeap->size; parent = child) {child = parent * 2;if (child < minHeap->size && minHeap->p[child + 1].weight < minHeap->p[child].weight) {child++;}if (temp <= minHeap->p[child].weight) {break;}else {minHeap->p[parent].weight = minHeap->p[child].weight;}}minHeap->p[parent].weight = temp;
}// 调整法建立最小堆(n)
void buildMinHeap(MinHeap* minHeap) {for (int i = minHeap->size / 2; i > 0; i--) {minHeapAdjust(minHeap, i);}
}// 判断最小堆是否为空
bool isEmpty(MinHeap* minHeap) {if (minHeap->size == 0) {return true;}return false;
}// 删除最小元素并返回
TreeNode* deleteMin(MinHeap* minHeap) {if (minHeap == NULL) {cout << "The min heap is not created." << endl;return 0;}if (isEmpty(minHeap)) {cout << "The min heap is empty." << endl;return 0;}TreeNode* minNode = (TreeNode*)malloc(sizeof(TreeNode));minNode->weight = minHeap->p[1].weight;minNode->lChild = minHeap->p[1].lChild;minNode->rChild = minHeap->p[1].rChild;int last = minHeap->p[minHeap->size--].weight;int parent = 0;int child = 0;for (parent = 1; parent * 2 <= minHeap->size; parent = child) {child = parent * 2;if (child != minHeap->size && minHeap->p[child + 1].weight < minHeap->p[child].weight) {child++;}if (last < minHeap->p[child].weight) {break;}else {minHeap->p[parent].weight = minHeap->p[child].weight;minHeap->p[parent].lChild = minHeap->p[child].lChild;minHeap->p[parent].rChild = minHeap->p[child].rChild;}}minHeap->p[parent].weight = last;minHeap->p[parent].lChild = minHeap->p[minHeap->size + 1].lChild;minHeap->p[parent].rChild = minHeap->p[minHeap->size + 1].rChild;return minNode;
}// 先序遍历(递归)
void preOrderTraverse(TreeNode* head) {if (head) {cout << head->weight << " ";preOrderTraverse(head->lChild);preOrderTraverse(head->rChild);}
}// 构造哈夫曼树
TreeNode* buildHuffmanTree(MinHeap* minHeap) {TreeNode* huffmanTreeNode = NULL;buildMinHeap(minHeap);for (int i = 0; i < minHeap->capacity - 1; i++) {huffmanTreeNode = (TreeNode*)malloc(sizeof(TreeNode));huffmanTreeNode->lChild = deleteMin(minHeap); huffmanTreeNode->rChild = deleteMin(minHeap); huffmanTreeNode->weight = huffmanTreeNode->lChild->weight + huffmanTreeNode->rChild->weight;insertMinHeap(minHeap, huffmanTreeNode);}huffmanTreeNode = deleteMin(minHeap);return huffmanTreeNode;
}int main() {MinHeap* minHeap = NULL;minHeap = createMinHeap(SIZE);for (int i = 0; i < SIZE; i++) {minHeap->p[i + 1].weight = SIZE - i;minHeap->p[i + 1].lChild = NULL;minHeap->p[i + 1].rChild = NULL;minHeap->size++;}cout << "原始数据序列:" << endl;printMinHeap(minHeap);buildMinHeap(minHeap);cout << "最小堆数据序列:" << endl;printMinHeap(minHeap);TreeNode* huffumanTree = NULL;huffumanTree = buildHuffmanTree(minHeap);cout << "哈夫曼树先序遍历序列:" << endl;preOrderTraverse(huffumanTree);cout << endl;system("pause");return 0;
}

5. 运行结果截图如下:

6. 哈夫曼树构造如下:

转载于:https://www.cnblogs.com/yiluyisha/p/9335233.html

最小堆实现哈夫曼树构造相关推荐

  1. 哈夫曼树构造以及代码实现

    哈夫曼树构造以及代码实现 什么是哈夫曼树 理解哈夫曼树 哈夫曼树的构造 哈夫曼树构造-代码实现 什么是哈夫曼树 构造一颗二叉树,该树的带权路径长度达到最小,称为最优二叉树,也称为哈夫曼树(Huffma ...

  2. 哈夫曼树构造哈夫曼编码

    在传输文字时,经常要将文字转换成二进制字符串.所以我们希望编码最短,但是又想保证它的唯一性.哈夫曼树具有最小带权路径长度,用来实现编码就可以编码最短,所以用哈夫曼树来构造编码.而前缀编码就可以保证在解 ...

  3. 算法学习笔记10——应用哈夫曼树构造最短的不等长编码方案

    内容: (1)设需要编码的字符集为{d1, d2, -, dn},它们出现的频率为{w1, w2, -, wn},应用哈夫曼树构造最短的不等长编码方案. 提示: 哈夫曼树(Huffman Tree), ...

  4. 哈夫曼树构造算法的正确性证明

    哈夫曼树构造 1.哈夫曼树的定义 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree). 2.哈夫曼树的构造 假 ...

  5. 【Lua】哈夫曼树构造算法的分析与实现

    哈夫曼树构造算法分析 1.哈夫曼树中权重越大的叶子离根越近,采用贪心算法构造哈夫曼树,首先选中权重值小的叶子结点进行构造 2.步骤 构造森林全是根:根据n个给定结点的权重值{W1, W2-Wn}构成 ...

  6. 贪心算法之最小堆实现霍夫曼编码

    贪心算法之最小堆实现霍夫曼编码 实现之前需要学习的地方: 如果你不了解堆.堆的插入.堆的删除,可以先看下我前面几篇博客 http://blog.csdn.net/u011068702/article/ ...

  7. 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

    在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉 ...

  8. c语言哈夫曼树构造代码

    c语言哈夫曼树构造代码 博主就很掘的一个人,最近学哈夫曼树,想着用指针去实现,觉得用指针实现,内存消耗会更少,写到后面发现越来与麻烦,且内存开销并没有减少,于是还是使用结构体数组中规中矩的去实现哈夫曼 ...

  9. 【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算

    1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R ...

最新文章

  1. 阅读论文《一种金融市场预测的深度学习模型FEPA》(1)
  2. java 判断一个字符串是否由数字组成的_Java中怎样判断一个字符串是否是数字
  3. 改变listview中item选中时文字的颜色
  4. 马化腾又要发红包!648亿港元,最多腾讯2%股份,我酸了...
  5. Oracle不完全恢复-主动恢复和incarnation/RMAN-20208/RMAN-06004
  6. html5 datalist 选中option选项后的触发事件
  7. nyoj 买水果(组合数求法与分析)
  8. 我用Python爬虫获取数据,分析双色球中奖概率,差点就中了
  9. c++11并发与多线程
  10. 矩阵基础 |共轭转置、单位矩阵、矩阵的迹
  11. 如何让电脑同时访问内网和外网:为电脑手动添加路由
  12. 如何制定客户留存策略_运营参考|促活、拉新、留存、变现,7种策略教你做好用户运营...
  13. 悉尼大学商业数据科学与计算机学院,留学攻略—澳洲悉尼大学数据科学专业
  14. ReactNative开发之在原生页面调用rn控件
  15. 免费下载国内各大音乐平台歌曲
  16. STM32使用串口1配合DMA接收不定长数据,大大减轻CPU载荷。
  17. 解决JSCH的sftp连接时出现的com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stre
  18. BootStrap 统计分析 浅析
  19. org.springframework.boot:spring-boot-starter-velocity:unknown以及其他依赖因spring版本不同无法加载
  20. 接口快速复制到 Postman 接口快速修改参数调试

热门文章

  1. 联通能否后来居上关键在自身
  2. 工程经济预算与成本问题及措施
  3. 寻找#Moonbeam全球大使
  4. [转]《零基础入门深度学习》系列文章(教程+代码)
  5. 使用 npx 安装react
  6. 阿里开源Zeus概述
  7. loam 框架流程描述
  8. java字体设置,包括大小,颜色,加粗,下划线,对齐,斜体的设置
  9. 实变函数与泛函分析课本pdf_实变函数与泛函分析基础(第三版)同步辅导及习题全解...
  10. 信息系统项目管理师核心考点(九)组织结构类型