Skip to content

Commit fbf7b05

Browse files
committed
sys: Add Disjoint-set data structure
Add a set of Disjoint-set functions (`find`, `union`) to handle queries between sets. Signed-off-by: James Roy <[email protected]>
1 parent 31ef45e commit fbf7b05

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

include/zephyr/sys/uf.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2025 James Roy <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file
9+
* @defgroup union_find_apis Disjoint-set
10+
* @ingroup datastructure_apis
11+
*
12+
* @brief Disjoint-set implementation
13+
*
14+
* This implements a disjoint-set (union-find) that guarantees
15+
* O(alpha(n)) runtime for all operations. The algorithms and
16+
* naming are conventional per existing academic and didactic
17+
* implementations, c.f.:
18+
*
19+
* https://en.wikipedia.org/wiki/Disjoint-set_data_structure
20+
*
21+
* @{
22+
*/
23+
24+
#ifndef ZEPHYR_INCLUDE_SYS_UF_H_
25+
#define ZEPHYR_INCLUDE_SYS_UF_H_
26+
27+
#include <stdint.h>
28+
29+
/**
30+
* @brief Disjoint-set node structure
31+
*/
32+
struct uf_node {
33+
/** @cond INTERNAL_HIDDEN */
34+
struct uf_node *parent;
35+
uint16_t rank;
36+
/** @endcond */
37+
};
38+
39+
/**
40+
* @brief Initialize a disjoint-set.
41+
*/
42+
static inline void uf_makeset(struct uf_node *node)
43+
{
44+
node->parent = node;
45+
node->rank = 0;
46+
}
47+
48+
/**
49+
* @brief Find the root of the disjoint-set.
50+
*/
51+
struct uf_node *uf_find(struct uf_node *node);
52+
53+
/**
54+
* @brief Merge two nodes into the same disjoint-set.
55+
*/
56+
void uf_union(struct uf_node *node1, struct uf_node *node2);
57+
58+
/** @} */
59+
60+
#endif /* ZEPHYR_INCLUDE_SYS_UF_H_ */

lib/utils/uf.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2025 James Roy <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/sys/uf.h>
8+
9+
struct uf_node *uf_find(struct uf_node *node)
10+
{
11+
while (node != node->parent) {
12+
node->parent = node->parent->parent;
13+
node = node->parent;
14+
}
15+
16+
return node;
17+
}
18+
19+
void uf_union(struct uf_node *node1, struct uf_node *node2)
20+
{
21+
struct uf_node *root1 = uf_find(node1);
22+
struct uf_node *root2 = uf_find(node2);
23+
24+
if (root1 == root2) {
25+
return;
26+
}
27+
28+
if (root1->rank < root2->rank) {
29+
root1->parent = root2;
30+
} else if (root1->rank > root2->rank) {
31+
root2->parent = root1;
32+
} else {
33+
root2->parent = root1;
34+
root1->rank++;
35+
}
36+
}

0 commit comments

Comments
 (0)