Return to the Lecture Notes Index

15-200 Lecture 27 (November 13, 2006)

Union-Find

Earlier this semester, we created a Set class using LinkedLists. This class supported a very broad array of Set operations. But, for this particular problem, we only need to do two things: look in a set to see if an item is there (find) and unite two sets (union). And, since the Set lab, we've learned about trees, which added a powerful tool to our kit. Let's see how we can use trees to represent sets in a way that leads to efficient Union and Find operations.

Again, imagine a graph, with each vertex as its own set. Now imagine that each set of vertices is a tree. So before we connect any edges, each vertex is its own tree, and the graph is a forest of trees.

We'll use an array to represent the trees. Create an array, with each index of the array representing the corresponding vertex of the graph. Place a sentinel value, -1, into each array element. We will use this sentinel value to denote the root of the tree. Before we connect any edges, each vertex is its own tree, so its the root. -1 represents the root of the tree set.

  
    0    1    2    3    4    5    6    7
  [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1]
  

Now I decide to connect 7 to 1. They are in different sets, so I connect them.

  
    0    1    2    3    4    5    6    7
  [-1] [-1] [-1] [-1] [-1] [-1] [-1] [ 1]
  

The parent of 7 is now 1, and 7 is no longer the root of the tree. If we want to find 7's parent, we simply look at its value, which is 1. To find 1's parent, we look at its value, which is -1, indicating that 1 has no parent and is the root of the tree.

Now I decide to connect 2 to 1. They are in different sets, so I connect them.

  
    0    1    2    3    4    5    6    7
  [-1] [-1] [ 1] [-1] [-1] [-1] [-1] [ 1]
  

Now I decide to connect 0 to 7. They are in different sets, so I connect them. Notice, though, that since 7 is in set 1, 0 was made a child of 1. This makes the tree wider, rather than deeper, making the find faster.

  
    0    1    2    3    4    5    6    7
  [ 1] [-1] [ 1] [-1] [-1] [-1] [-1] [ 1]
  

I want to connect 4 to 6. They are in different sets, so I connect them.

  
    0    1    2    3    4    5    6    7
  [ 7] [-1] [ 1] [-1] [ 6] [-1] [-1] [ 1]
  

I want to connect 5 to 6. They are in different sets, so I connect them.

  
    0    1    2    3    4    5    6    7
  [ 7] [-1] [ 1] [-1] [ 6] [ 6] [-1] [ 1]
  

Note that connect 4 to 5 would now create a cycle.

I want to connect 1 to 4. They are in different sets, so I connect them. Notice again, that I connected the root of 1's tree, 1, to the root of 4's tree, 6. Remember, we always attach one root to another, never to another non-root node.

  
    0    1    2    3    4    5    6    7
  [ 7] [ 6] [ 1] [-1] [ 6] [ 6] [-1] [ 1]
  

How do you find out what set a particular vertex of the graph belongs to? You simply follow its ancestors up until you find an array element with a value of -1. At this point, all vertices except 3 are in the same set -- 6. 6 is the only element with a value of -1. Vertex 6 is the root of the tree consisting of all of the vertices in the graph.

The operation that connects to vertices by changing the array element value of one to be the other is called union. The operation that finds the root of a particular vertex's tree is called find.