3 * Set operations for AVL trees
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 const struct xyla_bt_treeops avl_ops =
34 { xyla_avl_join, xyla_avl_splitat, xyla_avl_splitroot };
36 /*----- Main code ---------------------------------------------------------*/
38 int xyla_avl_unisect(struct xyla_bt_nodecls *cls,
39 struct xyla_bt_node **uni_out, int *uniht_out,
40 struct xyla_bt_node **isect_out, int *isectht_out,
41 struct xyla_bt_node **aroot, int aht,
42 struct xyla_bt_node **broot, int bht)
44 /* Compute the union and intersection of two trees.
46 * On entry, *AROOT and *BROOT are the roots of two trees a and b, with
47 * their respective heights in AHT and BHT, if the caller knows them, or -1
48 * otherwise. The trees are considered to represent sets, with one element
49 * per node; the element is determined by the `key' node-class operation.
50 * On exit, *UNI_OUT points to the root of a tree containing (one copy of)
51 * each element present in either a or b, and *ISECT_OUT points to the root
52 * of a tree containing the other copy of each element present in both a
53 * and b; the heights of the output trees are stored in *UNIHT_OUT and
54 * *ISECTHT_OUT, if these are not null. If AROOT and/or BROOT are distinct
55 * from UNI_OUT and ISECT_OUT, then null pointers are stored in them. The
56 * original trees are destroyed; each node in the original operands trees
57 * ends up in exactly one of the result trees.
59 * Returns `XYLA_RC_OK'.
62 struct xyla_bt_setopstack stack[XYLA_AVL_HTMAX];
65 if (aht < 0) aht = xyla_avl_height(AVL_NODE(*aroot));
66 if (bht < 0) bht = xyla_avl_height(AVL_NODE(*broot));
68 rc = xyla_bt_unisect(cls, uni_out, uniht_out, isect_out, isectht_out,
69 aroot, &aht, broot, &bht,
70 &avl_ops, stack, XYLA_AVL_HTMAX);
75 int xyla_avl_diffsect(struct xyla_bt_nodecls *cls,
76 struct xyla_bt_node **diff_out, int *diffht_out,
77 struct xyla_bt_node **isect_out, int *isectht_out,
78 struct xyla_bt_node **aroot, int aht,
79 struct xyla_bt_node **broot)
81 /* Compute the set difference of the two operand trees.
83 * On entry, *AROOT and *BROOT are the roots of two trees a and b, with a's
84 * height in AHT, if the caller knows it, or -1 otherwise (the height of b
85 * is not significant). The trees are considered to represent sets, with
86 * one element per node; the element is determined by the `key' node-class
87 * operation. On exit, *DIFF_OUT points to the root of a tree containing
88 * each element of a but not b, and *ISECT_OUT points to the root of a tree
89 * containing each element of a that's also in b; the heights of the output
90 * trees are stored in *DIFFHT_OUT and *ISECTHT_OUT, if these are not null.
91 * If AROOT and/or BROOT are distinct from DIFF_OUT and ISECT_OUT, then
92 * null pointers are stored in them. The original a tree is destroyed;
93 * each node in the original operands trees ends up in exactly one of the
94 * result trees. The input b tree is unchanged.
96 * Returns `XYLA_RC_OK'.
99 struct xyla_bt_setopstack stack[XYLA_AVL_HTMAX];
102 if (aht < 0) aht = xyla_avl_height(AVL_NODE(*aroot));
104 rc = xyla_bt_diffsect(cls, diff_out, diffht_out, isect_out, isectht_out,
106 &avl_ops, stack, XYLA_AVL_HTMAX);
111 /*----- That's all, folks -------------------------------------------------*/