#include <stdio.h>
#include <stdlib.h>
typedef struct{
int p;
int q;
}pair;
/***************************************************************
:
: p q ,p q 。
: i i, 0<=i<N。 p q ,
, p q .
: N , M ,
O(M*N)
: m: , n: n
***************************************************************/
void connectivity_quickfind(pair pairs[], int m, int id[], int n)
{
int p, q, i, j, t;
for (i = 0; i < n; ++i)
{
id[i] = i;
}
for (i = 0; i < m; ++i)
{
p = pairs[i].p;
q = pairs[i].q;
if (id[p] == id[q]) continue;
for (t = id[p], j = 0; j < n; ++j)
{
if (id[j] == t) id[j] = id[q];
}
printf("%d, %d
", p, q);
}
}
/***************************************************************
:
。
, , 。
, 。
M , , :
, 。 ,
(root), 。
, , N 、M
O(M*N/2)
***************************************************************/
void connectivity_quickunion(pair pairs[], int m, int id[], int n)
{
int p, q, i, j, k;
for (i = 0; i < n; ++i)
{
id[i] = i;
}
for (k = 0; k < m; ++k)
{
p = pairs[k].p;
q = pairs[k].q;
for (i = p; i != id[i]; i = id[i]);
for (j = q; j != id[j]; j = id[j]);
if (i == j) continue;
id[i] = j;
printf("%d, %d
", p, q);
}
}
/***************************************************************
:
: ,
, 。
N , 2*lgN 。
***************************************************************/
void connectivity_weighted_quickunion(pair pairs[], int m, int id[], int n)
{
int i, j, k, p, q;
int *sz = (int *)malloc(n*sizeof(int));
if (NULL == sz)
{
printf("
No enough memory!!!
");
return;
}
for (i = 0; i < n; i++)
{
id[i] = i;
sz[i] = 1;
}
for (k = 0; k < m; ++k)
{
p = pairs[k].p;
q = pairs[k].q;
for (i = p; i != id[i]; i = id[i]);
for (j = q; j != id[j]; j = id[j]);
if (i == j) continue;
if (sz[i] < sz[j])
{
id[i] = j;
sz[j] += sz[i];
}
else
{
id[j] = i;
sz[i] += sz[i];
}
printf("%d, %d
", p, q);
}
free(sz);
}
/***************************************************************
:
***************************************************************/
void connectivity_pathcompression_weighted_quickunion(pair pairs[], int m, int id[], int n)
{
int i, j, k, p, q;
int *sz = (int *)malloc(n*sizeof(int));
if (NULL == sz)
{
printf("
No enough memory!!!
");
return;
}
for (i = 0; i < n; i++)
{
id[i] = i;
sz[i] = 1;
}
for (k = 0; k < m; ++k)
{
p = pairs[k].p;
q = pairs[k].q;
//
for (i = p; i != id[i]; i = id[i])
{
id[i] = id[id[i]];
}
for (j = q; j != id[j]; j = id[j])
{
id[i] = id[id[i]];
}
if (i == j) continue;
//
if (sz[i] < sz[j])
{
id[i] = j;
sz[j] += sz[i];
}
else
{
id[j] = i;
sz[i] += sz[i];
}
printf("%d, %d
", p, q);
}
}
int main()
{
#if 1
pair pairs[] = {
{ 3, 4 }, { 4, 9 }, { 8, 0 }, { 2, 3 },
{ 5, 6 }, { 2, 9 }, { 5, 9 }, { 7, 3 },
{ 4, 8 }, { 5, 6 }, { 0, 2 }, { 6, 1 },
{ 5, 8 },
};
#else
pair pairs[] = {
{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
{ 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
{ 8, 9 }, { 9, 0 },
};
#endif
int m = sizeof(pairs) / sizeof(pairs[0]);
int n = 10;
int id[10];
printf("
connectivity_quickfind:
");
connectivity_quickfind(pairs, m, id, n);
printf("
connectivity_quickunion:
");
connectivity_quickunion(pairs, m, id, n);
printf("
connectivity_weighted_quickunion:
");
connectivity_weighted_quickunion(pairs, m, id, n);
printf("
connectivity_pathcompression_weighted_quickunion:
");
connectivity_pathcompression_weighted_quickunion(pairs, m, id, n);
return 0;
}