COMP 261 Lecture 12 Disjoint Sets Kruskal's Algorithm 7 5 B A 3 2 I 6 D 9 4 10 1 C 1 17 H 6 8 10 E 3 J 14 G 4 25 18 23 F • Questions: – How to find the smallest edge efficiently? – How to efficiently determine if an edge connects two trees or not? Refining Kruskal's algorithm • Given: a graph with N nodes and E weighted edges forest ← a set of N sets of nodes, each containing one node of the graph edges ← a priority queue of all the edges: 〈n1, n2, length〉 priority: short edges first spanningTree ← an empty set of edges Repeat until forest contains only one tree or edges is empty: 〈n1, n2, length〉 ← dequeue(edges) If n1 and n2 are in different sets in forest then merge the two sets in forest What's the Add edge to the spanningTree cost? return spanningTree • Implementing forest : – set of sets with two operations: • findSet(n1) =?= findSet(n2) = "find" the set that n is in • merge(s1, s2) = replace s1, s2 by their "union" Implementing sets of sets 1: forest = set of sets of nodes: – findSet(n1) • iterate through all sets, calling s.contains(n1) – merge (s1 , s2) • add each element of s1 to s2 and remove s1 – cost? A F H B C E D G J I Implementing sets of sets 2: forest = mark each node with ID of its set – findSet(n1): • look up n1.setID – merge(s1 , s2) • iterate through all nodes, changing IDs of nodes in s1 – cost? A 1 B 2 C 2 D 3 E 2 F 1 G 3 H 1 I 1 J 3 Union–Find structure 3: forest: set of inverted trees of nodes: • Each set represented by a linked tree with links pointing towards the root Z A T C G X J D E U S R K R Y Q W H N • The nodes in these trees are the nodes of the graph Union–Find structure MakeSet(x): x.parent ← x add x to set Find(A) = A Find(G) = A Find(E) = A Find(W) = A … Z A Find(x) if x.parent = x Recursively go return x up to the root else root ← Find(x.parent) return root T C G E R Q W Union–Find structure Union(x, y): xroot ← Find(x) yroot ← Find(y) if xroot = yroot return else xroot.parent ← yroot remove xroot from set. Union(E,T) A G xroot yroot T C E R y x Q W Union–Find structure Union(x, y): xroot ← Find(x) yroot ← Find(y) if xroot = yroot return else xroot.parent ← yroot remove xroot from set. Union(x,y) = Union(y,x)? Union(E,U) J A xroot U G T C E R yroot K x Q W y Union–Find structure Union(x, y): xroot ← Find(x) yroot ← Find(y) if xroot = yroot return else xroot.parent ← yroot remove xroot from set. Union(U,E) J A yroot U G T C E R xroot x K y Q W Union(x,y) = Union(y,x)? • Order will affect tree depth (search complexity) Union–Find structure • find(Q), union(E, Z), union(H, K), union(Y, G) Z A C G X T J D E U S R K R Y Q W H N • Problem: the trees can get unreasonably long • Solutions: shorten the trees; add shorter trees to longer Union–Find: Better MakeSet(x): x.parent ← x add x to set x.depth ← 0 Union(x, y) keeping track of depth lets us add the smaller tree to the larger tree Find(x) if x.parent = x Modify tree to keep paths short return x else root ← Find(x.parent) return root Amortised cost < 5! xroot ← Find(x) yroot ← Find(y) if xroot = yroot then return if xroot.depth < yroot.depth xroot.parent ← yroot remove xroot from set else yroot.parent ← xroot remove yroot from set if xroot.depth = yroot.depth xroot.depth ++ Union–Find structure • find(Q), union(E, Z), union(H, K), union(Y, G) Z0 A4 T0 C3 G0 E2 R0 X3 J2 D2 S0 U1 K0 R1 Y1 Q1 W0 H0 N0 Applications • Union-Find is very efficient for a collection of sets if – All sets are disjoint. – Only asking for same set membership and merging two sets. • Inefficient for – enumerating the elements of a set – removing an element from a set • Doesn't work if the sets could share elements Exercise: B 18 1 A 12 11 7 14 13 8 B C D 3 E 17 J 19 15 20 F G A 16 9 I H D 6 5 10 4 C 2 E F G H I J
© Copyright 2026 Paperzz