最小堆实现哈夫曼树构造
2018-07-19 13:16
435 查看
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. 哈夫曼树构造如下:
相关文章推荐
- 哈夫曼树的构造以及编码实现
- [C语言]哈夫曼树(Huffman)的构造与实现
- 构造哈夫曼树 求哈弗曼编码 (贪心算法实现)算法导论p232
- 哈夫曼树构造及代码实现
- 构造哈夫曼树并求带权路径长度(c语言/CodeBlocks实现)
- java实现最小堆(通过构造函数构造最小堆,相当于堆排序)
- 构造哈夫曼树的Java实现,未通过亲自编程实现,记一下。
- 设计程序以实现构造哈夫曼树的哈夫曼算法
- 【转】MATLAB实现构造Euler环游图的算法——数学建模
- 请使用socket相关函数(非curl)实现如下功能:构造一个post请求,发送到指定httpserver的指定端口的指定请求路径(如http://www.example.com:8080/test)
- 编译原理(七) 算符优先分析法(构造算符优先关系表算法及C++实现)
- 数据结构学习笔记(三) 树形结构之利用堆构造哈夫曼树
- 中国象棋程序的设计与实现(八)-如何构造一个棋子(車馬炮等)
- 简洁常用权限系统的设计与实现(三):维护和利用节点的深度level,迭代实现树的构造
- 哈夫曼树编码及解码,链表实现
- JAVA实现哈夫曼树
- 哈夫曼树的构造算法,哈夫曼编码算法
- 通过构造Hash冲突实现各种语言的拒绝服务攻击
- 二叉查找树的构造与遍历[Java实现]
- PoC TBCP消息解析和构造的JAVA实现