您的位置:首页 > 理论基础 > 数据结构算法

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

2017-03-14 21:00 573 查看
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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  class