要求:根据一组数,构建一棵赫夫曼树。
输入:
有多组测试数据,每组第一行是输入的元素数目,第二行是输入的各个元素。元素数目为0代表结束。输出:
每一组先输出Case: x,然后遍历树输出,树的每层都比上层空4个空格。
样例输入:
4
7 5 2 4
7
8 12 34 16 20 7 23
0
样例输出:
Case: 1
18
7
11
5
6
2
4
Case: 2
120
50
23
27
12
15
7
8
70
34
36
16
20
0
代码如下:
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct Node {
int elem;
Node* left;
Node* right;
Node(int e)
:elem(e) {
this->left = nullptr;
this->right = nullptr;
}
Node() {
};
bool operator < (const Node& n)const {
return elem > n.elem;
}
};
typedef Node* Tree;
typedef priority_queue<Node> Pqueue;
int Read(Pqueue& pq) {
int n;
cin >> n;
if (!n)
return 0;
int num;
for (int i = 0; i < n; ++i) {
cin >> num;
pq.push(Node(num));
}
return 1;
}
void CreateHffTree(Tree T, Pqueue& pq) {
while (pq.size() > 1) {
Node* pa = new Node;
*pa = pq.top();
pq.pop();
Node* pb = new Node;
*pb = pq.top();
pq.pop();
Node parent;
parent.elem = pa->elem + pb->elem;
parent.left = pa;
parent.right = pb;
pq.push(parent);
}
Node top = pq.top();
pq.pop();
T->elem = top.elem;
T->left = top.left;
T->right = top.right;
}
void PrintHffTree(Tree T, int depth) {
for (int i = 0; i < 4 * depth; ++i)
cout << " ";
cout << T->elem << endl;
if (T->left != nullptr)
PrintHffTree(T->left, depth + 1);
if (T->right != nullptr)
PrintHffTree(T->right, depth + 1);
}
void DestroyHffTree(Tree T) {
if (T->left != nullptr)
DestroyHffTree(T->left);
if (T->right != nullptr)
DestroyHffTree(T->right);
delete T;
}
int main()
{
int cnt = 0;
while (true) {
Tree head = new Node;
Pqueue pq;
if (Read(pq) == false)
break;
CreateHffTree(head, pq);
cout << "Case: " << ++cnt << endl;
PrintHffTree(head, 0);
DestroyHffTree(head);
}
//system("pause");
return 0;
}
代码说明:
用到了优先队列,每次都pop最小的两个,然后再push这两个的parent。优先队列的元素是结构体,需要手写比较函数(operator<)。注意写在struct里面的operator重载不要漏了const(两个const都不能少!)
千万注意:
在CreateHffTree函数中,一定要写Node* na = new Node; *na = pq.top(); ..... parent.left = na;而不能写Node na = pq.top();.... parent.left = &na;
因为后者na成了局部变量,parent.left指向一个局部变量的地址没有意义,因为它马上就会被释放,导致这棵树最后根本没有建立!因为建立的部分都被栈释放掉了!必须要手动申请一块空间来,这样空间放在了堆里面,而不是放在栈里面!