最小堆实现哈夫曼树构造
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
最小堆实现哈夫曼树构造相关推荐
- 哈夫曼树构造以及代码实现
哈夫曼树构造以及代码实现 什么是哈夫曼树 理解哈夫曼树 哈夫曼树的构造 哈夫曼树构造-代码实现 什么是哈夫曼树 构造一颗二叉树,该树的带权路径长度达到最小,称为最优二叉树,也称为哈夫曼树(Huffma ...
- 哈夫曼树构造哈夫曼编码
在传输文字时,经常要将文字转换成二进制字符串.所以我们希望编码最短,但是又想保证它的唯一性.哈夫曼树具有最小带权路径长度,用来实现编码就可以编码最短,所以用哈夫曼树来构造编码.而前缀编码就可以保证在解 ...
- 算法学习笔记10——应用哈夫曼树构造最短的不等长编码方案
内容: (1)设需要编码的字符集为{d1, d2, -, dn},它们出现的频率为{w1, w2, -, wn},应用哈夫曼树构造最短的不等长编码方案. 提示: 哈夫曼树(Huffman Tree), ...
- 哈夫曼树构造算法的正确性证明
哈夫曼树构造 1.哈夫曼树的定义 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree). 2.哈夫曼树的构造 假 ...
- 【Lua】哈夫曼树构造算法的分析与实现
哈夫曼树构造算法分析 1.哈夫曼树中权重越大的叶子离根越近,采用贪心算法构造哈夫曼树,首先选中权重值小的叶子结点进行构造 2.步骤 构造森林全是根:根据n个给定结点的权重值{W1, W2-Wn}构成 ...
- 贪心算法之最小堆实现霍夫曼编码
贪心算法之最小堆实现霍夫曼编码 实现之前需要学习的地方: 如果你不了解堆.堆的插入.堆的删除,可以先看下我前面几篇博客 http://blog.csdn.net/u011068702/article/ ...
- 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树
在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉 ...
- c语言哈夫曼树构造代码
c语言哈夫曼树构造代码 博主就很掘的一个人,最近学哈夫曼树,想着用指针去实现,觉得用指针实现,内存消耗会更少,写到后面发现越来与麻烦,且内存开销并没有减少,于是还是使用结构体数组中规中矩的去实现哈夫曼 ...
- 【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算
1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R ...
最新文章
- 阅读论文《一种金融市场预测的深度学习模型FEPA》(1)
- java 判断一个字符串是否由数字组成的_Java中怎样判断一个字符串是否是数字
- 改变listview中item选中时文字的颜色
- 马化腾又要发红包!648亿港元,最多腾讯2%股份,我酸了...
- Oracle不完全恢复-主动恢复和incarnation/RMAN-20208/RMAN-06004
- html5 datalist 选中option选项后的触发事件
- nyoj 买水果(组合数求法与分析)
- 我用Python爬虫获取数据,分析双色球中奖概率,差点就中了
- c++11并发与多线程
- 矩阵基础 |共轭转置、单位矩阵、矩阵的迹
- 如何让电脑同时访问内网和外网:为电脑手动添加路由
- 如何制定客户留存策略_运营参考|促活、拉新、留存、变现,7种策略教你做好用户运营...
- 悉尼大学商业数据科学与计算机学院,留学攻略—澳洲悉尼大学数据科学专业
- ReactNative开发之在原生页面调用rn控件
- 免费下载国内各大音乐平台歌曲
- STM32使用串口1配合DMA接收不定长数据,大大减轻CPU载荷。
- 解决JSCH的sftp连接时出现的com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stre
- BootStrap 统计分析 浅析
- org.springframework.boot:spring-boot-starter-velocity:unknown以及其他依赖因spring版本不同无法加载
- 接口快速复制到 Postman 接口快速修改参数调试