2.编写一个程序,从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结 点的权值,建立哈夫曼树。要求: (1)输出存放哈夫曼树的数组HT的初态和终态;(来找bug叭)就剩8个啦

//头文件

#pragma once
typedef struct {
    char ch;
    int freq;
} CharNode;

typedef struct {
    int freq;
    CharNode* charNode;
} MinHeapNode;

typedef struct {
    MinHeapNode* nodes;
    int size;
    int capacity;
} MinHeap;

typedef struct BinTreeNode {
    char data;
    struct BinTreeNode* left;
    struct BinTreeNode* right;
} BinTreeNode;
// 函数声明
void swap(MinHeapNode**, MinHeapNode**);
void minHeapify(MinHeap*, int);
MinHeapNode* extractMin(MinHeap*);
void decreaseKey(MinHeap*, int, MinHeapNode*);
void buildMinHeap(MinHeap*);
MinHeapNode* createMinHeapNode(CharNode*);
void printHeap(MinHeap*);
BinTreeNode* createHuffmanTree(MinHeap*);

//源代码.cpp

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include "erchashuqueson2.h"
// 全局变量
#define MinHeap* heap;

int main() {
    int n; int i;
    printf("Enter the number of characters: ");
    scanf("%d", &n);

    CharNode charNodes[n]; // 存储字符和频率

    printf("Enter the characters and their frequencies:\n");
    for (i = 0; i < n; i++) {
        scanf("%c %d", &charNodes[i].ch, &charNodes[i].freq);
    }

    &heap = (*heap)malloc(sizeof(MinHeap));
    &heap->nodes = (MinHeapNode*);malloc(sizeof(MinHeapNode) * n);
    &heap->size = 0;
    &heap->capacity = n;

    // 将字符节点转换为最小堆节点并构建最小堆
    for (i = 0; i < n; i++) {
        MinHeapNode* node = createMinHeapNode(&charNodes[i]);
        heap->nodes[heap->size++] = *node;
    }

    buildMinHeap(heap);

    // 使用最小堆构建哈夫曼树
    BinTreeNode* HuffmanTree = createHuffmanTree(heap);

    // 输出哈夫曼树的数组初态
    printf("Initial heap state:\n");
    printHeap(heap);

    // 这里可以添加代码来输出哈夫曼树的终态,例如遍历树的代码

    // 清理内存
    free(heap->nodes);
    free(heap);

    // 注意:这里没有释放BinTreeNode分配的内存,实际使用中需要添加这部分代码

    return 0;
}
// 交换两个最小堆节点
void swap(MinHeapNode* a, MinHeapNode* b) {
    MinHeapNode temp = *a;
    *a = *b;
    *b = temp;
}
// 向下调整最小堆
void minHappify(MinHeap* h, int idx;)
{
    int smallest = idx;
    int left = 2 * idx + 1;
    int right = 2 * idx + 2;

    if (left < h->size && h->nodes[left].freq < h->nodes[smallest].freq) {
        smallest = left;
    }

    if (right < h->size && h->nodes[right].freq < h->nodes[smallest].freq) {
        smallest = right;
    }

    if (smallest != idx) {
        swap(&h->nodes[idx], &h->nodes[smallest]);
        minHeapify(h, smallest);
    }
}

// 从最小堆中提取最小元素
MinHeapNode* extractMin(MinHeap* h) {
    if (h->size == 0) return NULL;
    MinHeapNode* minNode = h->nodes[0];
    h->nodes[0] = h->nodes[h->size - 1];
    h->size--;
    minHeapify(h, 0);
    return minNode;
}

// 构建最小堆
void buildMinHeap(MinHeap* h) {
    int i;
    for (i = h->size / 2 - 1; i >= 0; i--) {
        minHeapify(h, i);
    }
}

// 创建一个新的最小堆节点
MinHeapNode* createMinHeapNode(CharNode* cNode) {
    MinHeapNode* node = (MinHeapNode*)malloc(sizeof(MinHeapNode));
    node->freq = cNode->freq;
    node->charNode = cNode;
    return node;
}

// 打印最小堆
void printHeap(MinHeap* h) {
    for (int i = 0; i < h->size; i++) {
        printf("(%c, %d) ", h->nodes[i]->charNode->ch, h->nodes[i]->freq);
    }
    printf("\n");
}

// 使用最小堆构建哈夫曼树
BinTreeNode* createHuffmanTree(MinHeap* h) {
    BinTreeNode* left, * right, * top;

    while (h->size > 1) {
        left = createHuffmanTree(h); // 取出最小频率的节点
        right = createHuffmanTree(h);

        top = (BinTreeNode*)malloc(sizeof(BinTreeNode));
        top->data = '\0'; // 内部节点用空字符表示
        top->left = left;
        top->right = right;
        top->left->right = top->right->left = NULL; // 重置子节点的左右指针

        MinHeapNode* newNode = createMinHeapNode((CharNode*)malloc(sizeof(CharNode)));
        newNode->freq = left->freq + right->freq; // 新节点的频率是左右子树频率之和
        newNode->charNode = NULL; // 内部节点没有字符

        insertNode(h, newNode); // 将新节点加入最小堆
    }

    return h->nodes[0] ? h->nodes[0]->charNode : NULL;
}

// 插入节点到最小堆中
void insertNode(MinHeap* h, MinHeapNode* node) {
    if (h->size >= h->capacity) {
        printf("Heap overflow\n");
        return;
    }

    h->nodes[h->size] = *node;
    int i = h->size++;
    while (i != 0 && h->nodes[(i - 1) / 2].freq > h->nodes[i].freq) {
        swap(&h->nodes[(i - 1) / 2], &h->nodes[i]);
        i = (i - 1) / 2;
    }
}
 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

实践—认识

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值