Hoffman

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node {
    char ch;
    int freq;
    struct Node* left;
    struct Node* right;
} Node;

Node* createNode(char ch, int freq) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->ch = ch;
    node->freq = freq;
    node->left = NULL;
    node->right = NULL;
    return node;
}

void swap(Node** a, Node** b) {
    Node* temp = *a;
    *a = *b;
    *b = temp;
}

void minHeapify(Node** heap, int size, int i) {
    int smallest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < size && heap[left]->freq < heap[smallest]->freq) {
        smallest = left;
    }
    if (right < size && heap[right]->freq < heap[smallest]->freq) {
        smallest = right;
    }
    if (smallest != i) {
        swap(&heap[i], &heap[smallest]);
        minHeapify(heap, size, smallest);
    }
}

Node* extractMin(Node** heap, int* size) {
    if (*size == 0) return NULL;
    Node* min = heap[0];
    heap[0] = heap[*size - 1];
    (*size)--;
    minHeapify(heap, *size, 0);
    return min;
}

void insertHeap(Node** heap, int* size, Node* node) {
    (*size)++;
    int i = *size - 1;
    heap[i] = node;
    while (i > 0 && heap[(i - 1) / 2]->freq > heap[i]->freq) {
        swap(&heap[(i - 1) / 2], &heap[i]);
        i = (i - 1) / 2;
    }
}

Node* buildHuffmanTree(char letters[], int freqs[], int n) {
    Node* heap[100];
    int size = 0;
    for (int i = 0; i < n; i++) {
        insertHeap(heap, &size, createNode(letters[i], freqs[i]));
    }

    while (size > 1) {
        Node* left = extractMin(heap, &size);
        Node* right = extractMin(heap, &size);
        Node* merged = createNode('\0', left->freq + right->freq);
        merged->left = left;
        merged->right = right;
        insertHeap(heap, &size, merged);
    }
    return extractMin(heap, &size);
}

void decode(Node* root, char* s, char* result) {
    Node* current = root;
    int idx = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] == '0') {
            current = current->left;
        } else {
            current = current->right;
        }
        if (current->ch != '\0') {
            result[idx++] = current->ch;
            current = root;
        }
    }
    result[idx] = '\0';
}

int main() {
    char letters[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
    int freqs[] = {7, 19, 2, 6, 32, 3, 21, 10};
    int n = sizeof(letters) / sizeof(letters[0]);

    Node* root = buildHuffmanTree(letters, freqs, n);

    char s[101];
    scanf("%s", s);

    char result[101];
    decode(root, s, result);

    printf("%s\n", result);

    return 0;
}

 

posted @ 2025-11-19 13:30  我不是青山  阅读(0)  评论(0)    收藏  举报