【C++数据结构】哈夫曼树代码实现

本文介绍了如何使用C++编程实现哈夫曼树。包括HuffeManTree头文件和源文件,以及主程序main.cpp的详细内容,展示了哈夫曼编码的数据结构和构建过程。
摘要由CSDN通过智能技术生成

HuffeManTree.h

#pragma once
#include "Stack.h"  // 我自己写的栈
#include "Stack.cpp"

template<class T>
class CTree {
public:
    CTree(void);

public:
    T data = NULL;
    int weight = 1;
    CTree* lNode = nullptr;
    CTree* rNode = nullptr;
    string code = "";
};

template<class T>
class CHuffemanTree
{
public:
    CHuffemanTree(void);
    ~CHuffemanTree(void);

private:
    CTree<T>* head = nullptr;   // 树的头指针
    CStack<CTree<T>*> stack;  // 用来写哈夫曼树的栈
    int TotalWeight = 0;    //总权重
    string encode = "";         //字符串编码
    CStack<CTree<T>*> stack_tree; // 用来保存编码好的节点 

private:
    int GetLength(void); // 得到Stack栈的长度
    void Sort(void);  // 排序
    void WriteToCode(string str); // 把字符串写成编码
    void EnCode(CTree<T>* node, string code, int k); // 编码
    void Insert(T data); // 插入数据
    void CreateHuffemanTree(void); // 根据stack创建哈夫曼树
    void DeleteTree(CTree<T>* node);

public:
    void CreateHuffemanTree(string str); // 传入语句 生成相应的哈夫曼树
    int GetTotalWeight(void); // 得到总权重
    string GetEnCode(void); // 得到编码
    string GetDeCode(string str);  // 解码
    void Display(void); //显示
};

HuffeManTree.cpp

#include "HuffemanTree.h"

template<class T>
CTree<T>::CTree()
{
}

template<class T>
CHuffemanTree<T>::CHuffemanTree()
{
}

template<class T>
CHuffemanTree<T>::~CHuffemanTree()
{
     DeleteTree(head);
}

template<class T>
int CHuffemanTree<T>::GetLength(void)
{
    int s_length = stack.GetLength();
    int length = 0;
    for (int i = 0; i < s_length; i++) {
        CTree<T>* node = stack.At(i);
        length += node->weight;
    }
    return length;
}

template<class T>
void CHuffemanTree<T>::Sort(void)
{
    int s_length = stack.GetLength();

    for (int i = 0; i < s_length; i++) {
        for (int j = i + 1; j < s_length; j++) {
            if (stack.At(i)->weight < stack.At(j)->weight) {
                CTree<T>* temp;
                temp = stack.At(i);
                stack.At(i) = stack.At(j);
                stack.At(j) = temp;
            }
        }
    }
}

template<class T>
void CHuffemanTree<T>::WriteToCode(string str)
{
    for (int i = 0; i < str.length(); i++) {
        char c = str.at(i);
        for (int j = 0; j < stack_tree.GetLength(); j++) {
            CTree<T>* node = stack_tree.At(j);
            if (c == node->data) {
                encode += node->code;
            }
        }
    }
}

template<class T>
void CHuffemanTree<T>::EnCode(CTree<T>* node, string code, int k)
{
    if (nullptr == node) {
        return;
    }
    node->code = code;
    if (nullptr != node->lNode) {
        EnCode(node->lNode, node->code + "0", k + 1);
    }
    if (nullptr != node->rNode) {
        EnCode(node->rNode, node->code + "1", k + 1);
    }
    if (NULL != node->data) {   
        node->code = code;
        TotalWeight += k * node->weight;
        stack_tree.Push(node);
    }
}

template<class T>
void CHuffemanTree<T>::Insert(T data)
{
    for (int i = 0; i < stack.GetLength(); i++) {
        CTree<T>* temp = stack.At(i);
        if (data == temp->data) {
            temp->weight++;
            return;
        }
    }

    CTree<T>* node = new CTree<T>;
    node->data = data;
    stack.Push(node);
}

template<class T>
void CHuffemanTree<T>::CreateHuffemanTree(void)
{
    if (stack.GetLength() <= 0) {
        return;
    }

    if (stack.GetLength() == 1) {
        head = stack.At(0);
    }

    for (int i = 0; i < stack.GetLength() - 1;) {
        Sort();
        CTree<T>* node1 = stack.Pop();
        CTree<T>* node2 = stack.Pop();
        CTree<T>* node = new CTree<T>;
        node->lNode = node1;
        node->rNode = node2;
        node->weight = node1->weight + node2->weight;
        stack.Push(node);
        head = node;
    }
    EnCode(head, "", 0);
}

template<class T>
void CHuffemanTree<T>::DeleteTree(CTree<T>* node)
    {
        if (nullptr != node) {
            return;
        }
        DeleteTree(node->lNode);
        DeleteTree(node->rNode);
        delete node;
        node = nullptr;
    }

template<class T>
void CHuffemanTree<T>::CreateHuffemanTree(string str)
{
    for (int i = 0; i < str.length(); i++) {
        Insert(str.at(i));
    }
    CreateHuffemanTree();
    WriteToCode(str);
}

template<class T>
int CHuffemanTree<T>::GetTotalWeight(void)
{
    if (nullptr == head) {
        return 0;
    }
    return TotalWeight;
}

template<class T>
string CHuffemanTree<T>::GetEnCode(void)
{
    if (nullptr == head) {
        return "";
    }
    return encode;
}

template<class T>
string CHuffemanTree<T>::GetDeCode(string str)
{
    string result = "";
    string temp = "";
    for (int i = 0; i < str.length(); i++) {
        temp += str.at(i);
        for (int j = 0; j < stack_tree.GetLength(); j++) {
            CTree<T>* node = stack_tree.At(j);
            if (temp == node->code) {
                result += node->data;
                temp = "";
            }
        }
    }
    return result;
}

template<class T>
void CHuffemanTree<T>::Display(void)
{
    CStack<CTree<T>*> st;
    CTree<T>* node = head;

    while (nullptr != node) {
        if (NULL != node->data) {
            cout << "Data = " << node->data << " Weight = " << node->weight << " Code = " << node->code.c_str() << endl;
        }
        if (nullptr != node->rNode) {
            st.Push(node->rNode);
        }
        node = node->lNode;
        if (nullptr == node) {
            node = st.Pop();
        }
    }
}

main.cpp

void main() {
    CHuffemanTree<char> ht;
    ht.CreateHuffemanTree("hello world");
    ht.Display();
    cout << "TotalWeight = " << ht.GetTotalWeight() << endl;
    cout << "EnCode = " << ht.GetEnCode() << endl;
    cout << "DeCode = " << ht.GetDeCode(ht.GetEnCode()) << endl;
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值