You are on page 1of 63

1

2
3
4
5
6
7
8
9
a4
a1
a6
a7 S
a2
a3 a5
a8
a9

10
11
12
13
Set[i] 1 2 1 3 1 2 1 2 3 3 3 3

Item 0 1 2 3 4 5 6 7 8 9 10 11

Set 1 = {0, 2, 4, 6}, Set2={1, 5, 7}, Set3={3, 8, 9, 10, 11}

14
15
16
0 1 2 3 4

17
0 1 2 3 4

Union 0 and 4

0 1 2 3

18
0 1 2 3

Union 1 and 3

0 1 2

4 3

19
0 1 2

4 3

Union 0 and 1

0 1 2

4 3

20
0 1 2 -1 0 -1 1 0

0 1 2 3 4

4 3

21
-1 0 -1 1 0
Union of 2 and 0
0 1 2 3 4

-1 0 0 1 0

0 1 2 3 4

22
-1 0 -1 1 0
Union of 2 and 0
0 1 2 3 4

-1 0 0 1 0

0 1 2 3 4

23
24
class DisjSets
{
public:
explicit DisjSets( int numElements );

int find( int x ) const;


// int find( int x ); Mutator version
void unionSets( int root1, int root2 );

private:
vector<int> s;
};

25
/**
* Construct the disjoint sets object.
* numElements is the initial number of
* disjoint sets.
*/
DisjSets::DisjSets( int numElements )
: s( numElements )
{
for ( int i = 0; i < s.size( ); i++ )
s[ i ] = -1;
}
26
void DisjSets::unionSets( int root1, int root2 )
{

s[root2] = root1;

27
// Returns the root of the tree that contains x
int DisjSets::find( int x ) const
{
if ( s[ x ] < 0 )
return x;
else
return find( s[ x ] );
}

28
29
30
0 1 2 3 4 5 6 7

Union 0 and 4

0 1 2 3 5 6 7

31
Union 2 and 3

0 1 3 5 6 7

4
2

32
Union 5 and 6

0 1 3 6 7

4
2 5

33
Union 1 and 3

0 3 6 7

4
2 1 5

34
Union 0 and 6

3 6 7

0
2 1 5

4
Union 3 and 6

3 6 7

0
2 1 5

4
37
38
39
3 6 7

0
2 1 5

6 3 3 –3 0 6 –4 –1

0 1 2 3 4 5 6 7

40
/**
* Union two disjoint sets.
* For simplicity, we assume root1 and root2 are distinct
* and represent set names.
* root1 is the root of set 1.
* root2 is the root of set 2.
*/
void DisjSets::unionSets( int root1, int root2 )
{
if ( s[ root2 ] < s[ root1 ] ) { // root2 is heavier
// Update the weight
s[ root2] = s[ root2] + s[ root1 ] ;
s[ root1 ] = root2; // Make root2 new root
}
else
{
// Update the weight
s[ root1] = s[ root1] + s[ root2 ] ;
s[ root2 ] = root1; // Make root1 new root
}
} 41
0 1 2 3 4 5 6 7

Union 0 and 4

0 1 2 3 5 6 7

42
Union 2 and 3

0 1 3 5 6 7

4
2

43
Union 1 and 3

0 3 5 6 7

4
2 1

44
Union 0 and 6

0 3 5 7

6 4
2 1

45
Union 0 and 3

0 3 5 7

6 4
2 1

46
47
48
5 6 7

3 0

4
2 1

6 3 3 6 0 -1 –3 –1

0 1 2 3 4 5 6 7

49
/**
* Union two disjoint sets.
* For simplicity, we assume root1 and root2 are distinct
* and represent set names.
* root1 is the root of set 1.
* root2 is the root of set 2.
*/
void DisjSets::unionSets( int root1, int root2 )
{
if ( s[ root2 ] < s[ root1 ] ) // root2 is deeper
s[ root1 ] = root2; // Make root2 new root
else
{
if ( s[ root1 ] == s[ root2 ] )
s[ root1 ] ––; // Update height if same
s[ root2 ] = root1; // Make root1 new root
}
} 50
51
52
find(5)
6

3 0

4
2 1

53
find(5)
6 6

5
3 0 3 0

4 4
2 1 2 1

5 After find(5) tree is rearranged!

1 step closer 2 steps closer


54
55
/**
* Perform a find with path compression.
* Error checks omitted again for simplicity.
* Return the set containing x.
*/
int DisjSets::find( int x )
{
if ( s[ x ] < 0 )
return x;
else
return s[ x ] = find( s[ x ] );
}
56
/**
* Perform a find with path compression.
* Error checks omitted again for simplicity.
* Return the set containing x.
*/
int DisjSets::find( int x )
{
if( s[ x ] < 0 )
return x;
else class DisjSets
return s[ x ] = find( s[ x ] ); {
}
public:
explicit DisjSets( int numElements );

int find( int x ) const;


int find( int x ); Mutator version
void unionSets( int root1, int root2 );

private:
vector<int> s;
};
57
0 1 2 3 4

5 6 7 8 9

10 11 12 13 14

15 16 17 18 19

20 21 22 23 24

58
0 1 2 3 4

5 6 7 8 9

10 11 12 13 14

15 16 17 18 19

20 21 22 23 24

59
0 1 2 3 4

5 6 7 8 9

10 11 12 13 14

15 16 17 18 19

20 21 22 23 24

60
# of cells: N
# of walls: around 2N

0 1 2 3 4

5 6 7 8 9

10 11 12 13 14

15 16 17 18 19

20 21 22 23 24
62
63

You might also like