您的位置:首页 > 其它

【并查集】并查集实现原理以及应用

2017-08-16 12:44 288 查看

实现原理

一种树型数据结构,用于处理不相交集合(Disjoint Sets)的合并以及查询;一开始让所有元素独立成树,也就是只有根节点的树;然后根据需要将关联的元素(树)进行合并;合并的方式仅仅是将一棵树最原始的节点的父亲索引指向另一棵树;

初始化

初始化father:各个节点独立成树,并且其father[i]=-1,

father[i]

0 1 2 3 4 5 6 7 8 9

-1 -1 -1 -1 -1-1-1-1 -1

每个集合里面存放的都是自己的父节点,一直找,直到一个节点的值为负数,表示该节点为这个集合的根节点。根节点的绝对值,表示该集合有多少个元素

FindIdx查找该节点的根

因为每个节点的值为这个节点的父节点,所以以节点的值为下标,一直向上查找,直到一个节点的值为负数,那么找到了根节点。即:该集合的代表。

合并Union

找到两个节点的根节点,将他们的值相加存放到根节点1,根节点2的值为节点1的下标。这样将两个集合合并成以根节点1的集合中。

代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
using namespace std;

// 0   1   2   3   4   5    6
// -1  -1  -1  -1  -1  -1   -1
class UnionFindSet
{
public:
UnionFindSet(size_t size)
{
s.resize(size, -1);
}

size_t FindIdx(int x)//找该位置的根节点的下标
{
int root = x;
while (s[root] >= 0)
root = s[root];
return root;
}
void Union(int x1, int x2)//合并两个
{
int root1 = FindIdx(x1);
int root2 = FindIdx(x2);
if (root1 != root2)
{
s[root1] += s[root2];
s[root2] = root1;
}
}

bool IsSameSet(int x1, int x2)//判断两个集合是否相等
{
return FindIdx(x1) == FindIdx(x2);
}

size_t UnionSize()//求有几个集合 0 不是一个集合
{
size_t count = 0;
for (size_t i = 0; i < s.size(); ++i)
{
if (s[i] < 0)
count++;
}
return count - 1;
}

void PrintSet()
{
for (size_t i = 0; i < s.size(); ++i)
cout << i << "  ";
cout << endl;
for (size_t i = 0; i < s.size(); ++i)
{
if (s[i] < 0)
cout << s[i] << " ";
else
cout << s[i] << "  ";
}
cout << endl;
}
private:
vector<int> s;
};

void Test()
{
UnionFindSet un(8);
un.Union(1, 3); // -1
un.Union(3, 7);
un.Union(2, 4);
un.Union(4, 5);
un.Union(5, 6);

un.PrintSet();
cout<< un.UnionSize()<<endl;
}


初始化

// 0 1 2 3 4 5 6 7 8

// -1 -1 -1 -1 -1 -1 -1 -1 -1

(1)un.Union(1, 3);

查找1的根节点为 本身,查找 3的根节点为本身,然后合并,

1的值 = -1 + -1 = -2。//改集合有两个元素。

3的值 = 1;//3的父节点为节点1

// 0 1 2 3 4 5 6 7 8

// -1 -2 -1 1 -1 -1 -1 -1 -1

(2)un.Union(3, 7);

3的根节点为1,而1是该集合的代表,

7集合的代表为本身;

合并,

1的值为 = -2 + -1 = -3;//该集合有三个元素

7的值为 = 1。//节点1

应用

优化——路径压缩

思想

每次查找的时候,如果路径较长,则修改信息,以便下次查找的时候速度更快。

实现

第一步,找到根结点。

第二步,修改查找路径上的所有节点,将它们都指向根结点



图的最小生成树克鲁斯卡尔算法

图的最小生成树
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  并查集