C++ 链表实现构造Huffman树
2015-04-29 00:07
495 查看
浙江大学的教材《数据结构》第146页上的用堆构建哈夫曼链表树的函数的实现
1. 函数结构与书中代码相同。堆中元素为指向哈夫曼树的节点的指针:
3. 最后通过层序遍历输出哈夫曼树。
1. 函数结构与书中代码相同。堆中元素为指向哈夫曼树的节点的指针:
struct HuffmanTree { int weight; HuffmanTree* left; HuffmanTree* right; }; struct MinHeap { HuffmanTree** data; int size; int capacity; };2. 建堆函数不变,删除堆顶元素和插入元素函数由原来的直接对各个节点的数据进行过滤改为对指向节点的指针的过滤。把堆的元素设置为指向节点的指针的好处有两个,一个是方便通过操作指针来实现数据的插入和删除,另一个是可以构成链表把整个哈夫曼树连接起来。
3. 最后通过层序遍历输出哈夫曼树。
#include <stdio.h> #include <malloc.h> #include <cmath> struct HuffmanTree { int weight; HuffmanTree* left; HuffmanTree* right; }; HuffmanTree* CreateHuffman() { HuffmanTree* huffman = (HuffmanTree*) malloc(sizeof(HuffmanTree)); huffman->weight = 0; huffman->left = NULL; huffman->right = NULL; return huffman; } struct MinHeap { HuffmanTree** data; int size; int capacity; }; const int MINSIZE = -1; MinHeap* CreateMinHeap(int maxSize) { MinHeap* heap = (MinHeap*) malloc(sizeof(MinHeap)); heap->data = (HuffmanTree**) malloc(sizeof(HuffmanTree*) * (maxSize + 1)); for (int i = 0; i <= maxSize; i++) { heap->data[i] = (HuffmanTree*) malloc(sizeof(HuffmanTree)); heap->data[i]->left = NULL; heap->data[i]->right = NULL; heap->data[i]->weight = 0; } heap->size = 0; heap->capacity = maxSize; heap->data[0]->weight = MINSIZE; return heap; } MinHeap* BuildMinHeap(MinHeap* heap) { // 这里假设所有H->size个元素已经存在H->data[]->weight中 int i = heap->size / 2; int parent = i; int child = 0; int temp = 0; for (; i > 0; i--) { temp = heap->data[i]->weight; for (parent = i; parent * 2 <= heap->size; parent = child) { child = parent * 2; if ((child != heap->size) && (heap->data[child]->weight > heap->data[child + 1]->weight)) { child++; } if (temp <= heap->data[child]->weight) { break; } else { heap->data[parent]->weight = heap->data[child]->weight; } } heap->data[parent]->weight = temp; } return heap; } HuffmanTree* DeleteMinHeap(MinHeap* heap) { if (heap->size == 0) { printf("Heap is EMPTY.\n"); return NULL; } HuffmanTree* const lastNode = heap->data[heap->size]; heap->size--; HuffmanTree* const deletedNode = heap->data[1]; int parent = 1; int child = 2; for (; parent * 2 <= heap->size; parent = child) { child = parent * 2; if (child != heap->size && heap->data[child]->weight > heap->data[child + 1]->weight) { child++; } if (lastNode->weight > heap->data[child]->weight) { heap->data[parent] = heap->data[child]; } else { break; } } heap->data[parent] = lastNode; return deletedNode; } void InsertMinHeap(MinHeap* heap, HuffmanTree* huffman) { if (heap->size == heap->capacity) { printf("Heap is FULL.\n"); return; } int item = huffman->weight; heap->size++; int i = heap->size; for(; heap->data[i / 2]->weight > item; i /= 2) { heap->data[i] = heap->data[i / 2]; } heap->data[i] = huffman; } void BuildHuffman(MinHeap* heap) { HuffmanTree* huffman; BuildMinHeap(heap); const int SIZE = heap->size; for (int i = 1; i < SIZE; i++) { huffman = CreateHuffman(); huffman->left = DeleteMinHeap(heap); huffman->right = DeleteMinHeap(heap); huffman->weight = huffman->left->weight + huffman->right->weight; InsertMinHeap(heap, huffman); } } typedef HuffmanTree* QueueType; struct QNode { QueueType data; QNode* next; }; struct LinkQueue { QNode* rear; QNode* front; }; bool IsEmptyQ(LinkQueue* queue) { return (queue->front == NULL); } LinkQueue* CreateQueue() { LinkQueue* queue = (LinkQueue*) malloc(sizeof(LinkQueue)); queue->front = NULL; queue->rear = NULL; return queue; } void AddQ(LinkQueue* p, QueueType const item) { if (p->front == NULL) { QNode* newNode = (QNode*) malloc(sizeof(QNode)); newNode->data = item; newNode->next = NULL; p->front = newNode; p->rear = newNode; return; } QNode* newNode = (QNode*) malloc(sizeof(QNode)); newNode->data = item; newNode->next = NULL; p->rear->next = newNode; p->rear = newNode; } QueueType DeleteQ(LinkQueue* p) { if (p->front == NULL) { printf("Queue is empty."); return NULL; } QNode* temp = p->front; if (p->front == p->rear) { p->front = NULL; p->rear = NULL; QueueType item = temp->data; free(temp); return item; } p->front = p->front->next; QueueType item = temp->data; free(temp); return item; } int main(void) { MinHeap* testHeap = CreateMinHeap(5); for(int i = 1; i <= 5; i++) { testHeap->data[i]->weight = abs(10 * sin(i * i)); testHeap->size++; } BuildHuffman(testHeap); LinkQueue* queue = CreateQueue(); AddQ(queue, testHeap->data[1]); HuffmanTree* tempNode = NULL; while (!IsEmptyQ(queue)) { tempNode = DeleteQ(queue); printf("%d ", tempNode->weight); if (tempNode->left != NULL) { AddQ(queue, tempNode->left); } if (tempNode->right != NULL) { AddQ(queue, tempNode->right); } } return 0; }
相关文章推荐
- C++ 构造双向链表的实现代码
- C++ 构造双向链表的实现代码
- 构造双向链表根据访问频度动态调整位置_C++实现
- C++单项链表的构造及简单功能的实现
- C++Huffman树的构造实现及编码译码过程
- 数据结构的基础-单向链表所构造的栈 c++实现
- 请用c++ 实现stl中的string类,实现构造,拷贝构造,析构,赋值,比较,字符串相加,获取长度及子串等功能。
- C++模板实现链表
- C++实现双向链表
- c++实现双向链表的建立,插入,删除,合并,打印
- 用C++实现单向循环链表的解决方法
- C++实现链表翻转的两种方法
- 剑指offer第三十三题【两个链表的第一个公共结点】c++实现
- c++ 手动实现链表
- 双向链表---C++实现
- c++ 实现双向链表构造函数,拷贝构造函数,析构函数,输出操作符重载,赋值操作符重载,头插尾插,头删尾删,任意位置插入,任意位置删除,查找等
- 链表的实现基于C++
- c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)
- C++【拷贝构造】和【拷贝赋值】(实现自定义的string类)
- 约瑟夫环的链表C++实现