目录
引言
本人只是刚入门的萌新,记录一下自己的学习😊
树节点的创建
struct TreeNode
{
int weight;//权重
TreeNode* left, * right;//左右孩子
TreeNode():weight(0),left(NULL),right(NULL){}
TreeNode(int w) :weight(w), left(NULL), right(NULL) {}
TreeNode(int w,TreeNode* l,TreeNode* r) :weight(w), left(l), right(r) {}
};
HuffmanTree类
类的成员属性和方法
class HuffmanTree
{
public:
HuffmanTree();//空构造
HuffmanTree(const vector<int>& nums);//创建HuffmanTree
HuffmanTree(TreeNode* root);//拷贝构造
~HuffmanTree();//析构函数 释放内存
void preOrder(TreeNode* root);//前序遍历
void inOrder(TreeNode* root);//后序遍历
void postOrder(TreeNode* root);//中序遍历
void layerOrder();//层次遍历
int calculateWPL();//计算带权路径和
void deleteTree(TreeNode* root);//释放内存
TreeNode* copyTree(TreeNode* root);//树的拷贝
public:
TreeNode* root;
};
-
类的初始化-构造函数
空构造
HuffmanTree::HuffmanTree()
{
this->root = NULL;
}
有参构造 创建HuffmanTree
class myCmp
{
public:
bool operator()(TreeNode* left,TreeNode* right)
{
return left->weight > right->weight;
}
};
HuffmanTree::HuffmanTree(const vector<int>& nums)
{
//利用优先队列的特性 解决每次排序的时间浪费
priority_queue<TreeNode*, vector<TreeNode*>,myCmp > q;
for (int i = 0; i < nums.size(); i++)
{
TreeNode* node = new TreeNode(nums[i]);
q.push(node);
}
TreeNode* left = NULL, * right = NULL, *root = NULL;
while (q.size()!=1)
{
left = q.top();
q.pop();
right = q.top();
q.pop();
root = new TreeNode(left->weight + right->weight, left, right);
q.push(root);
}
this->root = root;
}
拷贝构造
HuffmanTree::HuffmanTree(TreeNode* root)
{
this->root = copyTree(root);
}
-
析构函数
HuffmanTree::~HuffmanTree()
{
if (this->root == NULL) return;
deleteTree(this->root);
}
-
类的方法
1.遍历
前序遍历
void HuffmanTree::preOrder(TreeNode* root)
{
if (root == NULL) return;
cout << root->weight << " ";
preOrder(root->left);
preOrder(root->right);
}
中序遍历
void HuffmanTree::inOrder(TreeNode* root)
{
if (root == NULL) return;
inOrder(root->left);
cout << root->weight << " ";
inOrder(root->right);
}
后序遍历
void HuffmanTree::postOrder(TreeNode* root)
{
if (root == NULL) return;
postOrder(root->left);
postOrder(root->right);
cout << root->weight << " ";
}
层次遍历
void HuffmanTree::layerOrder()
{
if (this->root == NULL) return;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int len = q.size();
TreeNode* tmp;
for (int i = 0; i < len; i++)
{
tmp = q.front();
q.pop();
cout << tmp->weight << " ";
if (tmp->left != NULL) q.push(tmp->left);
if (tmp->right != NULL) q.push(tmp->right);
}
cout << endl;
}
}
2.复制 WPL 释放内存
-
树的复制
TreeNode* HuffmanTree::copyTree(TreeNode* root)
{
if (root == NULL) return NULL;
TreeNode* left = copyTree(root->left);
TreeNode* right = copyTree(root->right);
root = new TreeNode(root->weight, left, right);
return root;
}
-
计算带权路径总和
广度优先搜索 与层次遍历的思想一致
int HuffmanTree::calculateWPL()
{
if (this->root == NULL) return 0;
int ans = 0,layer=0;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int len = q.size();
TreeNode* tmp;
for (int i = 0; i < len; i++)
{
tmp = q.front();
q.pop();
if (tmp->left != NULL) q.push(tmp->left);
if (tmp->right != NULL) q.push(tmp->right);
if (tmp->left == NULL && tmp->right == NULL) ans += (tmp->weight * layer);
}
layer++;
}
return ans;
}
-
释放内存
void HuffmanTree::deleteTree(TreeNode* root)
{
if (root == NULL) return;
deleteTree(root->left);
deleteTree(root->right);
delete root;
this->root = NULL;//将成员root置空 防止野指针
}
主程序
#include<iostream>
using namespace std;
#include<vector>
#include<queue>
struct TreeNode
{
int weight;
TreeNode* left, * right;
TreeNode():weight(0),left(NULL),right(NULL){}
TreeNode(int w) :weight(w), left(NULL), right(NULL) {}
TreeNode(int w,TreeNode* l,TreeNode* r) :weight(w), left(l), right(r) {}
};
class HuffmanTree
{
public:
HuffmanTree();//空构造
HuffmanTree(const vector<int>& nums);//创建HuffmanTree
HuffmanTree(TreeNode* root);//拷贝构造
~HuffmanTree();//析构函数 释放内存
void preOrder(TreeNode* root);//前序遍历
void inOrder(TreeNode* root);//后序遍历
void postOrder(TreeNode* root);//中序遍历
void layerOrder();//层次遍历
int calculateWPL();//计算带权路径和
void deleteTree(TreeNode* root);//释放内存
TreeNode* copyTree(TreeNode* root);//树的拷贝
public:
TreeNode* root;
};
class myCmp
{
public:
bool operator()(TreeNode* left,TreeNode* right)
{
return left->weight > right->weight;
}
};
void test01(const vector<int>& nums)//测试HuffmanTree是否成功创建
{
HuffmanTree t(nums);
cout << "前序遍历: "; t.preOrder(t.root); cout << endl;
cout << "中序遍历: "; t.inOrder(t.root);cout << endl;
cout << "后序遍历: "; t.postOrder(t.root);cout << endl;
cout << "层次遍历: " << endl; t.layerOrder();
cout << "带权路径总和(WPL): " << t.calculateWPL() << endl;
}
void test02(const vector<int>& nums)//验证拷贝构造函数
{
HuffmanTree t1(nums);
cout << "层次遍历: " << endl; t1.layerOrder();
HuffmanTree t2(t1.root);
cout << "层次遍历: " << endl; t1.layerOrder();
}
void test03(const vector<int>& nums)//测试内存释放
{
HuffmanTree t(nums);
t.deleteTree(t.root);//提前释放内存,查看是否与析构时冲突
cout << "层次遍历: " << endl; t.layerOrder();
}
int main()
{
vector<int> nums{ 10,20,50,100 };
//测试HuffmanTree是否成功创建
//test01(nums);
//验证拷贝构造函数
//test02(nums);
//测试内存释放
test03(nums);
return 0;
}
HuffmanTree::HuffmanTree()
{
this->root = NULL;
}
HuffmanTree::HuffmanTree(const vector<int>& nums)
{
//利用优先队列的特性 解决每次排序的时间浪费
priority_queue<TreeNode*, vector<TreeNode*>,myCmp > q;
for (int i = 0; i < nums.size(); i++)
{
TreeNode* node = new TreeNode(nums[i]);
q.push(node);
}
TreeNode* left = NULL, * right = NULL, *root = NULL;
while (q.size()!=1)
{
left = q.top();
q.pop();
right = q.top();
q.pop();
root = new TreeNode(left->weight + right->weight, left, right);
q.push(root);
}
this->root = root;
}
HuffmanTree::HuffmanTree(TreeNode* root)
{
this->root = copyTree(root);
}
HuffmanTree::~HuffmanTree()
{
if (this->root == NULL) return;
deleteTree(this->root);
}
void HuffmanTree::preOrder(TreeNode* root)
{
if (root == NULL) return;
cout << root->weight << " ";
preOrder(root->left);
preOrder(root->right);
}
void HuffmanTree::inOrder(TreeNode* root)
{
if (root == NULL) return;
inOrder(root->left);
cout << root->weight << " ";
inOrder(root->right);
}
void HuffmanTree::postOrder(TreeNode* root)
{
if (root == NULL) return;
postOrder(root->left);
postOrder(root->right);
cout << root->weight << " ";
}
void HuffmanTree::layerOrder()
{
if (this->root == NULL) return;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int len = q.size();
TreeNode* tmp;
for (int i = 0; i < len; i++)
{
tmp = q.front();
q.pop();
cout << tmp->weight << " ";
if (tmp->left != NULL) q.push(tmp->left);
if (tmp->right != NULL) q.push(tmp->right);
}
cout << endl;
}
}
int HuffmanTree::calculateWPL()
{
if (this->root == NULL) return 0;
int ans = 0,layer=0;
queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
int len = q.size();
TreeNode* tmp;
for (int i = 0; i < len; i++)
{
tmp = q.front();
q.pop();
if (tmp->left != NULL) q.push(tmp->left);
if (tmp->right != NULL) q.push(tmp->right);
if (tmp->left == NULL && tmp->right == NULL) ans += (tmp->weight * layer);
}
layer++;
}
return ans;
}
void HuffmanTree::deleteTree(TreeNode* root)
{
if (root == NULL) return;
deleteTree(root->left);
deleteTree(root->right);
delete root;
this->root = NULL;//将成员root置空 防止野指针
}
TreeNode* HuffmanTree::copyTree(TreeNode* root)
{
if (root == NULL) return NULL;
TreeNode* left = copyTree(root->left);
TreeNode* right = copyTree(root->right);
root = new TreeNode(root->weight, left, right);
return root;
}
1.测试HuffmanTree是否成功创建
void test01(const vector<int>& nums)//测试HuffmanTree是否成功创建
{
HuffmanTree t(nums);
cout << "前序遍历: "; t.preOrder(t.root); cout << endl;
cout << "中序遍历: "; t.inOrder(t.root);cout << endl;
cout << "后序遍历: "; t.postOrder(t.root);cout << endl;
cout << "层次遍历: " << endl; t.layerOrder();
cout << "带权路径总和(WPL): " << t.calculateWPL() << endl;
}
测试结果正确 实现树的创建
2.测试拷贝构造函数
void test02(const vector<int>& nums)//验证拷贝构造函数
{
HuffmanTree t1(nums);
cout << "层次遍历: " << endl; t1.layerOrder();
HuffmanTree t2(t1.root);
cout << "层次遍历: " << endl; t1.layerOrder();
}
两棵树的节点一致,并实现深拷贝(t1和t2析构时不发生冲突)
3.测试内存释放
void test03(const vector<int>& nums)//测试内存释放
{
HuffmanTree t(nums);
t.deleteTree(t.root);//提前释放内存,查看是否与析构时冲突
cout << "层次遍历: " << endl; t.layerOrder();
}
树被清空且不与析构函数发生冲突