From cc91e9eedd7b772f77129efcdd1b867f3f0b6985 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 24 Jun 2024 23:02:46 +0100 Subject: [PATCH] posts: union-find: add construction --- content/posts/2024-06-24-union-find/index.md | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/content/posts/2024-06-24-union-find/index.md b/content/posts/2024-06-24-union-find/index.md index 83722a9..54b1151 100644 --- a/content/posts/2024-06-24-union-find/index.md +++ b/content/posts/2024-06-24-union-find/index.md @@ -48,3 +48,33 @@ def connected_components(graph: Graph) -> list[set[Node]]: # Return a list of disjoint sets corresponding to each connected component return list(components.values()) ``` + +## Implementation + +I will show how to implement `UnionFind` for integers, though it can easily be +extended to be used with arbitrary types (e.g: by mapping each element +one-to-one to a distinct integer, or using a different set representation). + +### Representation + +Creating a new disjoint set is easy enough: + +```python +class UnionFind: + _parent: list[int] + _rank: list[int] + + def __init__(self, size: int): + # Each node is in its own set, making it its own parent... + self._parents = list(range(size)) + # ... And its rank 0 + self._rank = [0] * size +``` + +We represent each set through the `_parent` field: each element of the set is +linked to its parent, until the root node which is its own parent. When first +initializing the structure, each element is in its own set, so we initialize +each element to be a root and make it its own parent (`_parent[i] == i` for all +`i`). + +The `_rank` field is an optimization which we will touch on in a later section.