前几篇博客都是对并查集的union进行优化,其实并查集的find也可以优化,之前进行find操作时,
如下图,查找4的根节点需要4->3->2->1->0,当根节点数目特别多时,这样是很耗时的,
可以通过路径压缩来优化
当寻找4的根节点时,首先发现4的父节点3不是根节点,那么继续找3的父节点2是不是根节点
这里根据路径压缩,当发现4的父节点3不是根节点时,不再查找3,此时查找4的父节点的父节点2,就是将4指向2,查看2的父节点1是不是根节点
此时就算3是根节点也没关系,因为根节点会自己指向自己,那么4的父节点的父节点还是3,没有问题
这样就省去了判断3->2的步骤,下一步直接判断2的父节点1是不是根节点,如果不是,就将2指向2的父节点的父节点0
2的父节点0是根节点,查找结束,这样就省了运算时间
下面是程序实现
#include <iostream>
#include <cassert>
#include "UnionFindTestHelper.h"
using namespace std;
int main()
{
int n = 1000000;
UnionFindTestHelper::testUF4(n);
UnionFindTestHelper::testUF5(n);
return 0;
}
"UnionFindTestHelper.h"定义为
#include <iostream>
#include <ctime>
#include <cstdlib> //rand()º¯Êý
#include "UnionFind4.h"
#include "UnionFind5.h"
using namespace std;
namespace UnionFindTestHelper{
void testUF4(int n){
srand(time(NULL));
UF4::UnionFind uf = UF4::UnionFind(n);
time_t startTime = clock();
for(int i = 0; i < n; i++){
int a = rand()%n;
int b = rand()%n;
uf.unionElements(a, b);
}
for(int i = 0; i < n; i++){
int a =