1 # Tree |
1 # Tree |
2 |
2 |
3 <warning> |
3 UCX provides several low-level function for working with arbitrary tree structures, |
4 TODO: intro text |
4 as well as some high-level functions for trees that induce a certain order on the data they store. |
5 </warning> |
5 |
|
6 The following convenience macros allow you to declare and use simple tree structures. |
|
7 |
|
8 ```C |
|
9 #define CX_TREE_NODE_BASE(Type) |
|
10 |
|
11 #define cx_tree_node_base_layout |
|
12 ``` |
|
13 |
|
14 The `CX_TREE_NODE_BASE` macro declares four pointers of type `Type*`: |
|
15 `parent`, `children`, `last_child`, `prev`, and `next`, |
|
16 which must be placed as first member into your struct. |
|
17 |
|
18 You can use it for example like this: |
|
19 ```C |
|
20 typedef struct my_tree_node_s { |
|
21 CX_TREE_NODE_BASE(struct my_tree_node_s); |
|
22 int value; |
|
23 char *desc; |
|
24 } MyTreeNode; |
|
25 ``` |
|
26 |
|
27 The macro `cx_tree_node_base_layout` expands to the offsets of the above-mentioned pointers. |
|
28 It will become handy when calling the low-level tree functions which expect all offsets to be passed as arguments. |
|
29 |
|
30 Before diving into the function definitions, there are four function pointer declarations you should know. |
6 |
31 |
7 ```C |
32 ```C |
8 #include <cx/tree.h> |
33 #include <cx/tree.h> |
9 |
34 |
10 typedef void *(*cx_tree_node_create_func)( |
35 typedef void *(*cx_tree_node_create_func)( |
16 typedef int (*cx_tree_search_func)( |
41 typedef int (*cx_tree_search_func)( |
17 const void *node, const void *new_node); |
42 const void *node, const void *new_node); |
18 |
43 |
19 typedef void (*cx_tree_relink_func)( |
44 typedef void (*cx_tree_relink_func)( |
20 void *node, const void *old_parent, const void *new_parent); |
45 void *node, const void *old_parent, const void *new_parent); |
21 |
46 ``` |
22 #define CX_TREE_NODE_BASE(type) |
47 |
23 |
48 A `cx_tree_node_create_func` takes a pointer to the `data` the new node shall contain, and a `context` (which might be an allocator, for example). |
24 #define cx_tree_node_base_layout |
49 It shall allocate and return the created node, or `NULL` when node creation is not possible. |
25 ``` |
50 |
|
51 A `cx_tree_search_data_func` shall check if the `node` contains the `data`, or if a child node might contain the data. |
|
52 It shall return zero, when `node` contains the `data`. |
|
53 When a child node _might_ contain the data, the returned positive number shall indicate how close the match is. |
|
54 It is _not_ relevant if the data can actually be found in the subtree - the positive number also indicates that the data could be inserted in that subtree. |
|
55 Only when the entire subtree starting with `node` cannot contain the `data`, a negative number is supposed to be returned. |
|
56 |
|
57 A `cx_tree_search_func` behaves exactly the same, except that it does expect a pointer to the `data` but a pointer to a node structure. |
|
58 In combination with the `cx_tree_node_create_func`, when inserting nodes with the high-level functions, a `new_node` is created first, |
|
59 and then an appropriate insertion point is searched with the `cx_tree_search_func`. |
|
60 |
|
61 A `cx_tree_relink_func` is used when an intermediate node is removed from the tree and it's children need to be detached from |
|
62 the removed `old_parent` and attached to a `new_parent`. |
26 |
63 |
27 ## Create |
64 ## Create |
28 |
65 |
29 ```C |
66 ```C |
30 #include <cx/tree.h> |
67 #include <cx/tree.h> |