您的位置:首页 > 其它

最小堆实现哈夫曼树构造

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. 哈夫曼树构造如下:

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: