数据结构
优先级队列
priority_queue(C++STL中的优先级队列)
基本使用
![](https://i-blog.csdnimg.cn/blog_migrate/9a59d0e7ac8a2debf741c66b7d2aba1e.png)
q.top();
q.pop();
自定义优先级
![](https://i-blog.csdnimg.cn/blog_migrate/2e0354fa1eac1c22f95f7e69581fca84.png)
并查集
查找根节点
int unionsearch(int root) // 查找根结点
{
int son, tmp;
son = root;
while(root != pre[root])
root = pre[root];
while(son != root)
{
tmp = pre[son];
pre[son] = root;
son = tmp;
}
return root;
}
连接两个点
void join(int root1, int root2)
{
int x, y;
x = unionsearch(root1);
y = unionsearch(root2);
if(x != y)
pre[x] = y;
}
适用问题
- 给定两点,判断两个点是否连通
- 要使所有点都连通,还需要修几条路?
- 求图中有多少个连通块
哈夫曼树
哈夫曼树的构造
把每个叶节点按照权值的大小排序,先把最小的两个叶节点构成一个父节点,是他们的和。再以父节点为新的“叶节点” 参与后续大小的比较;继续这样构成新的二叉树。
#include <iostream>
#include <queue>
using namespace std;
struct node {
int weight;
node * left;
node * right;
node * parent;
};
struct cmp {
bool operator() (node & n1, node & n2) {
return n1.weight > n2.weight; // 按照weight从小到大的顺序出队
}
};
int main() {
priority_queue<node, vector<node>, cmp> q;
// 输入
...
node * root = NULL;
while (q.size() > 1) {
// 找到权值最小的两个节点
node * n1 = new node;
node * n2 = new node;
*n1 = q.top();
q.pop();
*n2 = q.top();
q.pop();
node * tmp = new node;
tmp->weight = n1->weight + n2->weight;
tmp->left = n1;
tmp->right = n2;
n1->parent = n2->parent = tmp;
q.push(tmp);
root = tmp;
}
}
适用问题
- 给定n个权值作为n个叶子结点,构造一棵二叉树,求该树的最小带权路径长度(所有叶子节点的带权路径长度之和,WPL)