c++ 并查集

Powered by Phantomlsh
大神勿喷。

在编程和算法设计的时候,我们经常会遇到一些保存集合的情况,例如使用Kruskal算法求最小生成树的时候。我们只关心一些元素是否在一个集合里而不关心它的顺序(如Kruskal算法中的边),我们可以使用一种新的数据结构——并查集。
我们对一些在同一集合的元素取其中一个作为代表元素(通常是递归中第一次遇到的),以它为树根建立一棵树,假设数组p记录节点的父结点,可以在拓展的时候直接拓展树。为了比较两个元素是否在同一个集合中,我们只要递归找到两个元素的代表元素,如果相同则在同意集合中。

一个并查集树的图示c++ 并查集_第1张图片

【路径优化】如图所示,我们发现,以A为代表元素的一个集合,如果要查B结点需要沿绿色线递归,再查C结点又要同样的递归,有大量的重复运算,效率低下。所以,我们可以把沿途查到的结点的父结点直接修改为代表元素,让下一次查询更快,这就是并查集的路径优化。
总的来说,并查集的查找代码可以写的极简(刘汝佳风格),用p数组记录集合树结点的父结点编号,则这个函数返回代表元素编号:

int findnode(int x){return p[x]==x ? x : p[x] = findnode(p[x]);}

解释:其中规定代表元素的父结点是自己。?:是if语句的表达式形式,利用c++里面赋值语句有返回值(就是赋的值)的性质进行路径优化同时返回。
这一行代码太经典,希望大家记住。

你可能感兴趣的:(算法,数据结构,算法,kruskal,c++,并查集)