优先队列指针类型自定义排序方法:
struct cmp { // 使用仿函数(函数对象)作为Compare双参判断式
bool operator()(const HTree &node1, const HTree &node2) {
return node1->weight > node2->weight;
}
};
priority_queue<HTree, vector<HTree>, cmp> q; // 小顶堆
/*
8
7 19 2 6 32 3 21 10
*/
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int weight;
struct node *lchild, *rchild;
string code;
} HTNode, *HTree;
struct cmp { // 使用仿函数(函数对象)作为Compare双参判断式
bool operator()(const HTree& node1, const HTree& node2) {
return node1->weight > node2->weight;
}
};
int WPL = 0;
HTree create_WPL(int n) {
priority_queue<HTree, vector<HTree>, cmp> q; // 小顶堆
for (int i = 0; i < n; i++) {
HTree temp = new HTNode();
int w;
cin >> w;
temp->weight = w;
temp->lchild = NULL;
temp->rchild = NULL;
temp->code = "";
q.push(temp);
}
for (int i = 0; i < n - 1; i++) { // 新加入结点共n-1个
HTree node1 = q.top();
q.pop();
HTree node2 = q.top();
q.pop();
HTree newNode = new HTNode();
newNode->weight = node1->weight + node2->weight;
newNode->lchild = node1;
newNode->rchild = node2;
newNode->code = "";
q.push(newNode);
WPL += newNode->weight; // 各个父节点的频度值加和即带权路径长度
}
return q.top();
}
vector<string> code;
void pre_coding(HTree node, string str) { // 前序遍历并编码
if (node->lchild == NULL && node->rchild == NULL) {
node->code = str;
code.push_back(str);
} else {
pre_coding(node->lchild, str + "0");
pre_coding(node->rchild, str + "1");
}
}
void levle_order(HTree root) { // 层次遍历
queue<HTree> qu;
qu.push(root);
HTree p = root;
while (!qu.empty()) {
p = qu.front();
cout << p->weight << " ";
qu.pop();
if (p->lchild)
qu.push(p->lchild);
if (p->rchild)
qu.push(p->rchild);
}
}
int main() {
int n;
cin >> n;
HTree H;
H = create_WPL(n);
levle_order(H); // 层次遍历
cout << endl;
pre_coding(H, "");
sort(code.begin(), code.end());
for (auto i : code)
cout << i << " ";
cout << endl;
cout << WPL;
return 0;
}0;
}
测试用例:
8
7 19 2 6 32 3 21 10
输出结果:
100 40 60 19 21 28 32 11 17 5 6 7 10 2 3
00 01 10000 10001 1001 1010 1011 11
261
即: