3 * Set operations for treaps
5 * (c) 2024 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Xyla, a library of binary trees.
12 * Xyla is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Lesser General Public License as published by the
14 * Free Software Foundation; either version 3 of the License, or (at your
15 * option) any later version.
17 * Xyla is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
20 * License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with Xyla. If not, see <https://www.gnu.org/licenses/>.
26 /*----- Header files ------------------------------------------------------*/
31 /*----- Tree operations ---------------------------------------------------*/
33 static int join_set(struct xyla_bt_nodecls *cls,
34 struct xyla_bt_node **root_out, int *rootht_out,
35 struct xyla_bt_node **left, int lht,
36 struct xyla_bt_node *mid,
37 struct xyla_bt_node **right, int rht)
41 rc = xyla_treap_join(cls, root_out, left, mid, right);
42 *rootht_out = 0; return (rc);
45 static int split_set_at(struct xyla_bt_nodecls *cls,
46 struct xyla_bt_node **left_out, int *lht_out,
47 struct xyla_bt_node **mid_out,
48 struct xyla_bt_node **right_out, int *rht_out,
49 struct xyla_bt_node **root, const void *key)
53 rc= xyla_treap_splitat(cls, left_out, mid_out, right_out, root, key);
54 *lht_out = *rht_out = 0; return (rc);
57 static int split_set_root(struct xyla_bt_node **left_out, int *lht_out,
58 struct xyla_bt_node **root_out,
59 struct xyla_bt_node **right_out, int *rht_out,
60 struct xyla_bt_node **root, int ht)
64 rc = xyla_treap_splitroot(left_out, root_out, right_out, root);
65 *lht_out = *rht_out = 0; return (rc);
68 static const struct xyla_bt_treeops treap_ops =
69 { join_set, split_set_at, split_set_root };
71 /*----- Main code ---------------------------------------------------------*/
73 int xyla_treap_unisect(struct xyla_bt_nodecls *cls,
74 struct xyla_bt_node **uni_out,
75 struct xyla_bt_node **isect_out,
76 struct xyla_bt_node **aroot,
77 struct xyla_bt_node **broot)
79 /* Compute the union and intersection of two trees.
81 * On entry, *AROOT and *BROOT are the roots of two trees a and b. The
82 * trees are considered to represent sets, with one element per node; the
83 * element is determined by the `key' node-class operation. On exit,
84 * *UNI_OUT points to the root of a tree containing (one copy of) each
85 * element present in either a or b, and *ISECT_OUT points to the root of a
86 * tree containing the other copy of each element present in both a and b.
87 * If AROOT and/or BROOT are distinct from UNI_OUT and ISECT_OUT, then null
88 * pointers are stored in them. The original trees are destroyed; each
89 * node in the original operands trees ends up in exactly one of the result
92 * Returns `XYLA_RC_OK'.
95 struct xyla_bt_setopstack stack[XYLA_TREAP_HTMAX];
98 rc = xyla_bt_unisect(cls, uni_out, 0, isect_out, 0,
100 &treap_ops, stack, XYLA_TREAP_HTMAX);
101 if (rc) xyla__treap_boundfail();
105 int xyla_treap_diffsect(struct xyla_bt_nodecls *cls,
106 struct xyla_bt_node **diff_out,
107 struct xyla_bt_node **isect_out,
108 struct xyla_bt_node **aroot,
109 struct xyla_bt_node **broot)
111 /* Compute the set difference of the two operand trees.
113 * On entry, *AROOT and *BROOT are the roots of two trees a and b. The
114 * trees are considered to represent sets, with one element per node; the
115 * element is determined by the `key' node-class operation. On exit,
116 * *DIFF_OUT points to the root of a tree containing each element of a but
117 * not b, and *ISECT_OUT points to the root of a tree containing each
118 * element of a that's also in b. If AROOT and/or BROOT are distinct from
119 * DIFF_OUT and ISECT_OUT, then null pointers are stored in them. The
120 * original a tree is destroyed; each node in the original operands trees
121 * ends up in exactly one of the result trees. The input b tree is
124 * Returns `XYLA_RC_OK'.
127 struct xyla_bt_setopstack stack[XYLA_TREAP_HTMAX];
130 rc = xyla_bt_diffsect(cls, diff_out, 0, isect_out, 0,
132 &treap_ops, stack, XYLA_TREAP_HTMAX);
133 if (rc) xyla__treap_boundfail();
137 /*----- That's all, folks -------------------------------------------------*/