4d20741a38a29227ab551b7579ff1a234bae2ca7
10 #include "cgds/safe_alloc.h"
11 #include "cgds/types.h"
18 * @brief Tree node, containing some generic data.
20 typedef struct TreeNode
{
21 void* data
; ///< Generic data contained in this node.
22 struct TreeNode
* parent
; ///< Pointer to parent node (NULL if node is root).
23 struct TreeNode
* firstChild
; ///< Pointer to the first child (if any).
24 struct TreeNode
* lastChild
; ///< Pointer to the last child (if any).
25 struct TreeNode
* prev
; ///< Pointer to the previous sibling (on the left).
26 struct TreeNode
* next
; ///< Pointer to the next sibling (on the right).
30 * @brief Generic multi-ary tree.
33 TreeNode
* root
; ///< Root node of the tree.
34 size_t dataSize
; ///< Size of *data at a tree node, in bytes.
35 UInt size
; ///< Count nodes in the tree.
39 * @brief Initialize an empty tree.
42 Tree
* tree
, ///< "this" pointer.
43 size_t dataSize
///< Size in bytes of a tree element.
47 * @brief Return an allocated and initialized tree.
50 size_t dataSize
///< Size in bytes of a tree node element.
54 * @brief Return an allocated and initialized tree.
55 * @param type Type at a tree node (int, char*, ...).
57 * Usage: Tree* tree_new(<Type> type)
59 #define tree_new(type) \
60 _tree_new(sizeof(type))
63 * @brief Copy constructor (shallow copy, ok for basic types).
66 Tree
* tree
///< "this" pointer.
70 * @brief Check if the tree is empty.
73 Tree
* tree
///< "this" pointer.
77 * @brief return current size of the tree (counting nodes).
80 Tree
* tree
///< "this" pointer.
84 * @brief Auxiliary function to get tree height.
86 UInt
_tree_height_rekursiv(
87 TreeNode
* treeNode
///< Pointer to a node in the "this" tree.
91 * @brief Return tree height (max depth from root to leaves).
94 Tree
* tree
///< "this" pointer.
98 * @brief Check if a sub-tree is a leaf (without children).
101 TreeNode
* treeNode
///< Pointer to a node in the "this" tree.
105 * @brief Initialize tree root when the tree is empty.
108 Tree
* tree
, ///< "this" pointer.
109 void* data
///< Pointer to data to be assigned.
113 * @brief Initialize tree root when the tree is empty.
114 * @param tree "this" pointer.
115 * @param data Data to be assigned.
117 * Usage: void tree_set_root(Tree* tree, void data)
119 #define tree_set_root(tree, data) \
121 typeof(data) tmp = data; \
122 _tree_set_root(tree, &tmp); \
126 * @brief Return data contained in a given tree node.
129 TreeNode
* treeNode
///< Pointer to a node in the "this" tree.
133 * @brief Retrieve data contained in a given tree node.
134 * @param treeNode Pointer to a node in the "this" tree.
135 * @param data Data to be assigned.
137 * Usage: void tree_get(TreeNode* treeNode, void data)
139 #define tree_get(treeNode, data) \
141 void* pData = _tree_get(treeNode); \
142 data = *((typeof(&data))pData); \
146 * @brief Set (alter) data at tree node passed as argument.
149 Tree
* tree
, ///< "this" pointer.
150 TreeNode
* treeNode
, ///< Pointer to a node in the "this" tree.
151 void* data
///< Pointer to data to be assigned.
155 * @brief Set (alter) data at tree node passed as argument.
156 * @param tree "this" pointer.
157 * @param treeNode Pointer to a node in the "this" tree.
158 * @param data Data to be assigned.
160 * Usage: void tree_set(Tree* tree, TreeNode* treeNode, void data)
162 #define tree_set(tree, treeNode, data) \
164 typeof(data) tmp = data; \
165 _tree_set(tree, treeNode, &tmp); \
169 * @brief Append a child to current node.
171 TreeNode
* _tree_add_child(
172 Tree
* tree
, ///< "this" pointer.
173 TreeNode
* treeNode
, ///< Pointer to a node in the "this" tree.
174 void* data
///< Pointer to data to be added.
178 * @brief Add a child to current node children.
179 * @param tree "this" pointer.
180 * @param treeNode Pointer to a node in the "this" tree.
181 * @param data Data to be added.
182 * @return The newly added tree node.
184 * Usage: TreeNode* tree_add_child(Tree* tree, TreeNode* treeNode, void data)
186 #define tree_add_child(tree,treeNode,data) \
188 typeof(data) tmp = data; \
189 _tree_add_child(tree, treeNode, &tmp); \
193 * @brief Add a sibling to current node (after it on the right).
195 TreeNode
* _tree_add_sibling(
196 Tree
* tree
, ///< "this" pointer.
197 TreeNode
* treeNode
, ///< Pointer to a node in the "this" tree.
198 void* data
///< Pointer to data to be added.
202 * @brief Add a sibling to current node (after it on the right).
203 * @param tree "this" pointer.
204 * @param treeNode Pointer to a node in the "this" tree.
205 * @param data Data to be added.
206 * @return The newly added tree node.
208 * Usage: TreeNode* tree_add_sibling(Tree* tree, TreeNode* treeNode, void data)
210 #define tree_add_sibling(tree, treeNode, data) \
212 typeof(data) tmp = data; \
213 _tree_add_sibling(tree, treeNode, &tmp); \
217 * @brief Auxiliary to remove a subtree.
219 void _tree_remove_rekursiv(
220 Tree
* tree
, ///< "this" pointer.
221 TreeNode
* treeNode
///< Pointer to a node in the "this" tree.
225 * @brief Remove the whole subtree rooted at 'treeNode'.
228 Tree
* tree
, ///< "this" pointer.
229 TreeNode
* treeNode
///< Pointer to a node in the "this" tree.
233 * @brief Remove children of the tree node given as argument.
236 Tree
* tree
, ///< "this" pointer.
237 TreeNode
* treeNode
///< Pointer to a node in the "this" tree.
241 * @brief Clear the entire tree.
244 Tree
* tree
///< "this" pointer.
248 * @brief Destroy the tree: clear it, and free 'tree' pointer.
251 Tree
* tree
///< "this" pointer.
259 * @brief Type of tree search: depth first or breadth first walk.
261 typedef enum TreeIteratorMode
{
262 IN_DEPTH
= 0, ///< Depth first.
263 IN_BREADTH
= 1 ///< Breadth first.
267 * @brief Iterator on a tree object.
269 typedef struct TreeIterator
{
270 Tree
* tree
; ///< Pointer to the tree to iterate over.
271 TreeNode
* current
; ///< Current iterator position.
272 TreeIteratorMode mode
; ///< Mode of iteration (in depth or in breadth).
276 * @brief Obtain an iterator object, starting at tree root.
278 TreeIterator
* tree_get_iterator(
279 Tree
* tree
, ///< Pointer to the tree to iterate over.
280 TreeIteratorMode mode
///< Mode of iteration (in depth or in breadth).
284 * @brief (Re)set current position inside tree to root.
287 TreeIterator
* treeI
///< "this" pointer.
291 * @brief Tell if there is some data at the current index.
294 TreeIterator
* treeI
///< "this" pointer.
298 * @brief Return current tree node.
300 TreeNode
* treeI_get_raw(
301 TreeIterator
* treeI
///< "this" pointer.
305 * @brief Get data at current tree node.
306 * @param treeI "this" pointer.
307 * @param data Data to be assigned.
309 * Usage: void treeI_get(TreeIterator* treeI, void data)
311 #define treeI_get(treeI, data) \
312 tree_get(treeI->current, data)
315 * @brief Set (alter) data at current tree node.
316 * @param treeI "this" pointer.
317 * @param data Data to be assigned.
319 * Usage: void treeI_set(TreeIterator* treeI, void data)
321 #define treeI_set(treeI, data) \
322 tree_set(treeI->tree, treeI->current, data)
325 * @brief Move current iterator position forward (toward leaves).
327 void treeI_move_next(
328 TreeIterator
* treeI
///< "this" pointer.
332 * @brief Free memory allocated for the iterator.
335 TreeIterator
* treeI
///< "this" pointer.