uf_name uf_find(uf_object *object)
void uf_make_set(uf_object *new_object)
void uf_union(uf_name class1, uf_name class2)
uf_object
is provided by the ADT user; the
data type uf_name
is chosen by the designer of the data
structure that implements the ADT. In implementing Union-Find, we
will assume that the data type uf_object
is a structure
and that the ADT designer may choose to include additional elements in
this structure.
uf_object
includes an element parent
that points to a
uf_object
; each equivalence class is a tree and its
"name" is a pointer to the root of the tree. The roots point
to themselves (which is just a convention; they could as well point to
NULL
).
uf_name uf_find(uf_object *object) { uf_object *root; for(root=object; root->parent!=root; root=root->parent); return root; } void uf_make_set(uf_object *new_object) { new_object->parent=new_object; } void uf_union(uf_name class1, uf_name class2) { class1->parent=class2; }
*object
,
we retrace the path from *object
to *root
once
more and suspend all of its nodes directly (rather than indirectly) below
*root
:
uf_name uf_find(uf_object *object) { uf_object *root, *next; for(root=object; root->parent!=root; root=root->parent); for(next=object->parent; next!=root; object=next, next=object->parent) object->parent=root; return root; }The other enhancement is an informed choice of the new root in
uf_union
: ideally, we would like the new root to come
from the deeper of the two trees. Unfortunately, keeping track of the
depth (which may change with each collapsing find) could be an
expensive proposition; fortunately, the choices suggested by depth are
well approximated by choices based on the notion of rank that
is defined as follows. Initially, each of the one-point equivalence
classes has rank 0; when two roots of an equal rank compete (fair
fight) for the distinction of becoming the root of the union, the
winner is chosen arbitrarily and its rank is then incremented by one;
when two roots of unequal rank compete (unfair fight) for the
distinction of becoming the root of the union, the root of the higher
rank wins. (A summary: your rank is the number of fair fights that you
have won.) This enhancement requires maintaing rank
as an
extra element in the structure uf_object
.
void uf_make_set(uf_object *new_object) { new_object->parent=new_object, new_object->rank=0; } void uf_union(uf_name class1, uf_name class2) { if(class1->rank < class2->rank) class1->parent=class2; else { class2->parent=class1; if(class1->rank==class2->rank) (class1->rank)++; } }