c++实现霍夫曼树

124 阅读2分钟

霍夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构,常用于数据编码和解码。它是一种最优的前缀编码树,通过根据字符出现频率构建一棵树,将出现频率高的字符编码为较短的位数,出现频率低的字符编码为较长的位数,从而实现数据压缩。

以下是一个简单的C++实现霍夫曼树的示例:

#include <iostream>
#include <queue>
#include <vector>

class HuffmanNode {
public:
    char data;
    int frequency;
    HuffmanNode* left;
    HuffmanNode* right;

    HuffmanNode(char d, int freq) : data(d), frequency(freq), left(nullptr), right(nullptr) {}

    // 用于优先队列的比较函数
    bool operator<(const HuffmanNode& other) const {
        return frequency > other.frequency; // 优先队列按照频率从小到大排列
    }
};

class HuffmanTree {
private:
    HuffmanNode* root;

    // 递归删除节点
    void deleteNodes(HuffmanNode* node) {
        if (node) {
            deleteNodes(node->left);
            deleteNodes(node->right);
            delete node;
        }
    }

public:
    HuffmanTree() : root(nullptr) {}

    // 构建霍夫曼树
    void buildTree(const std::vector<int>& frequencies) {
        std::priority_queue<HuffmanNode> pq;
        for (int i = 0; i < frequencies.size(); ++i) {
            if (frequencies[i] > 0) {
                pq.push(HuffmanNode(static_cast<char>(i), frequencies[i]));
            }
        }
        while (pq.size() > 1) {
            HuffmanNode* left = new HuffmanNode(0, 0);
            *left = pq.top();
            pq.pop();
            HuffmanNode* right = new HuffmanNode(0, 0);
            *right = pq.top();
            pq.pop();
            HuffmanNode* newNode = new HuffmanNode(0, left->frequency + right->frequency);
            newNode->left = left;
            newNode->right = right;
            pq.push(*newNode);
        }
        if (!pq.empty()) {
            root = new HuffmanNode(0, pq.top().frequency);
            *root = pq.top();
        }
    }

    // 递归打印霍夫曼树
    void printTreeHelper(HuffmanNode* node, std::string code) {
        if (node) {
            if (!node->left && !node->right) {
                std::cout << node->data << ": " << code << std::endl;
            }
            printTreeHelper(node->left, code + "0");
            printTreeHelper(node->right, code + "1");
        }
    }

    // 打印霍夫曼树
    void printTree() {
        if (root) {
            printTreeHelper(root, "");
        }
    }

    // 析构函数
    ~HuffmanTree() {
        deleteNodes(root);
    }
};

int main() {
    std::vector<int> frequencies(256, 0); // ASCII字符集共有256个字符
    frequencies['a'] = 5;
    frequencies['b'] = 9;
    frequencies['c'] = 12;
    frequencies['d'] = 13;
    frequencies['e'] = 16;
    frequencies['f'] = 45;

    HuffmanTree huffmanTree;
    huffmanTree.buildTree(frequencies);

    std::cout << "Huffman Tree:" << std::endl;
    huffmanTree.printTree();

    return 0;
}

在这个示例中,HuffmanNode 类表示霍夫曼树中的节点,包含了一个字符属性和一个频率属性,以及左右子节点的指针。HuffmanTree 类表示霍夫曼树本身,包含了一个指向根节点的指针。buildTree() 方法用于根据给定的字符频率构建霍夫曼树,printTree() 方法用于打印霍夫曼树的每个字符的编码。