几个并查集的C++实现
1、接口UF.h
#pragma once
class UF {
public:
virtual int GetSize() = 0;
virtual bool IsConnected(int p,int q) = 0;
virtual void UnionElements(int p,int q) = 0;
};
2、几种简单实现
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <windows.h>
#include "UF.h"
using namespace std;
class UF1 :public UF {
public:
UF1(int size) {
id = vector<int>(size);
for (int i = 0; i < (int)id.size(); i++) {
id[i] = i;
}
}
int GetSize() {
return id.size();
}
int find(int p) {
if (p < 0 && p >= (int)id.size()) {
return -1;
}
return id[p];
}
bool IsConnected(int p, int q) {
return find(p) == find(q);
}
void UnionElements(int p, int q) {
int pId = find(p);
int qId = find(q);
if (pId == qId) {
return;
}
for (int i = 0; i < (int)id.size(); i++) {
if ((int)id[i] == pId) {
id[i] = qId;
}
}
}
private:
vector<int> id;
};
class UF2 :public UF
{
public:
UF2(int size) {
parent = vector<int>(size);
for (int i = 0; i < (int)parent.size(); i++) {
parent[i] = i;
}
}
int GetSize() {
return parent.size();
}
int find(int p) {
if (p < 0 && p >= (int)parent.size()) {
return -1;
}
while (p != parent[p]) {
p = parent[p];
}
return p;
}
bool IsConnected(int p, int q) {
return find(p) == find(q);
}
void UnionElements(int p, int q) {
int pId = find(p);
int qId = find(q);
if (pId == qId) {
return;
}
parent[pId] = qId;
}
private:
vector<int> parent;
};
class UF3 :public UF
{
public:
UF3(int size) {
parent = vector<int>(size);
sz = vector<int>(size);
for (int i = 0; i < (int)parent.size(); i++) {
parent[i] = i;
sz[i] = 1;
}
}
int GetSize() {
return parent.size();
}
int find(int p) {
if (p < 0 && p >= (int)parent.size()) {
return -1;
}
while (p != parent[p]) {
p = parent[p];
}
return p;
}
bool IsConnected(int p, int q) {
return find(p) == find(q);
}
void UnionElements(int p, int q) {
int pId = find(p);
int qId = find(q);
if (pId == qId) {
return;
}
if (sz[pId] < sz[qId]) {
parent[pId] = qId;
sz[qId] += sz[pId];
}
else {
parent[qId] = pId;
sz[pId] += sz[qId];
}
}
private:
vector<int> parent;
vector<int> sz;
};
class UF4 :public UF
{
public:
UF4(int size) {
parent = vector<int>(size);
rank = vector<int>(size);
for (int i = 0; i < (int)parent.size(); i++) {
parent[i] = i;
rank[i] = 1;
}
}
int GetSize() {
return parent.size();
}
int find(int p) {
if (p < 0 && p >= (int)parent.size()) {
return -1;
}
while (p != parent[p]) {
p = parent[p];
}
return p;
}
bool IsConnected(int p, int q) {
return find(p) == find(q);
}
void UnionElements(int p, int q) {
int pId = find(p);
int qId = find(q);
if (pId == qId) {
return;
}
if (rank[pId] < rank[qId]) {
parent[pId] = qId;
}
else if (rank[qId] < rank[pId]) {
parent[qId] = pId;
}
else{
parent[qId] = pId;
rank[pId] += 1;
};
}
private:
vector<int> parent;
vector<int> rank;
};
class UF5 :public UF
{
public:
UF5(int size) {
parent = vector<int>(size);
rank = vector<int>(size);
for (int i = 0; i < (int)parent.size(); i++) {
parent[i] = i;
rank[i] = 1;
}
}
int GetSize() {
return parent.size();
}
int find(int p) {
if (p < 0 && p >= (int)parent.size()) {
return -1;
}
while (p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
bool IsConnected(int p, int q) {
return find(p) == find(q);
}
void UnionElements(int p, int q) {
int pId = find(p);
int qId = find(q);
if (pId == qId) {
return;
}
if (rank[pId] < rank[qId]) {
parent[pId] = qId;
}
else if (rank[qId] < rank[pId]) {
parent[qId] = pId;
}
else {
parent[qId] = pId;
rank[pId] += 1;
};
}
private:
vector<int> parent;
vector<int> rank;
};
class UF6 :public UF
{
public:
UF6(int size) {
parent = vector<int>(size);
rank = vector<int>(size);
for (int i = 0; i < (int)parent.size(); i++) {
parent[i] = i;
rank[i] = 1;
}
}
int GetSize() {
return parent.size();
}
int find(int p) {
if (p < 0 && p >= (int)parent.size()) {
return -1;
}
if (p != parent[p]) {
parent[p] = find(parent[p]);
}
return parent[p];
}
bool IsConnected(int p, int q) {
return find(p) == find(q);
}
void UnionElements(int p, int q) {
int pId = find(p);
int qId = find(q);
if (pId == qId) {
return;
}
if (rank[pId] < rank[qId]) {
parent[pId] = qId;
}
else if (rank[qId] < rank[pId]) {
parent[qId] = pId;
}
else {
parent[qId] = pId;
rank[pId] += 1;
};
}
private:
vector<int> parent;
vector<int> rank;
};
void testtime(UF*uf, int count) {
int size = uf->GetSize();
srand((unsigned)time(NULL));
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
for (int i = 0; i < count; i++) {
int a = rand() % size;
int b = rand() % size;
uf->UnionElements(a, b);
}
for (int i = 0; i < count; i++) {
int a = rand() % size;
int b = rand() % size;
uf->IsConnected(a, b);
uf->IsConnected(a, b);
}
QueryPerformanceCounter(&t2);
printf("Use Time:%f\n", (t2.QuadPart - t1.QuadPart)*1.0 / tc.QuadPart);
}
int main(void)
{
int size = 1000000;
int count = 1000000;
UF3 myuf3 = UF3(size);
testtime(&myuf3, count);
UF4 myuf4 = UF4(size);
testtime(&myuf4, count);
UF5 myuf5 = UF5(size);
testtime(&myuf5, count);
UF6 myuf6 = UF6(size);
testtime(&myuf6, count);
system("pause");
return 0;
}