src/ucx/avl.h

changeset 251
fae240d633fc
parent 250
b7d1317b138e
child 259
2f5dea574a75
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/ucx/avl.h	Tue Oct 17 16:15:41 2017 +0200
     1.3 @@ -0,0 +1,327 @@
     1.4 +/*
     1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 + *
     1.7 + * Copyright 2017 Olaf Wintermann. All rights reserved.
     1.8 + *
     1.9 + * Redistribution and use in source and binary forms, with or without
    1.10 + * modification, are permitted provided that the following conditions are met:
    1.11 + *
    1.12 + *   1. Redistributions of source code must retain the above copyright
    1.13 + *      notice, this list of conditions and the following disclaimer.
    1.14 + *
    1.15 + *   2. Redistributions in binary form must reproduce the above copyright
    1.16 + *      notice, this list of conditions and the following disclaimer in the
    1.17 + *      documentation and/or other materials provided with the distribution.
    1.18 + *
    1.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    1.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.29 + * POSSIBILITY OF SUCH DAMAGE.
    1.30 + */
    1.31 +
    1.32 +
    1.33 +/**
    1.34 + * @file avl.h
    1.35 + * 
    1.36 + * AVL tree implementation.
    1.37 + * 
    1.38 + * This binary search tree implementation allows average O(1) insertion and
    1.39 + * removal of elements (excluding binary search time).
    1.40 + * 
    1.41 + * @author Mike Becker
    1.42 + * @author Olaf Wintermann
    1.43 + */
    1.44 +
    1.45 +#ifndef UCX_AVL_H
    1.46 +#define UCX_AVL_H
    1.47 +
    1.48 +#include <ucx/ucx.h>
    1.49 +#include <ucx/allocator.h>
    1.50 +#include <inttypes.h>
    1.51 +
    1.52 +#ifdef	__cplusplus
    1.53 +extern "C" {
    1.54 +#endif
    1.55 +
    1.56 +/**
    1.57 + * UCX AVL Node type.
    1.58 + * 
    1.59 + * @see UcxAVLNode
    1.60 + */
    1.61 +typedef struct UcxAVLNode UcxAVLNode;
    1.62 +
    1.63 +/**
    1.64 + * UCX AVL Node.
    1.65 + */
    1.66 +struct UcxAVLNode {
    1.67 +    /**
    1.68 +     * The key for this node.
    1.69 +     */
    1.70 +    intptr_t key;
    1.71 +    /**
    1.72 +     * Data contained by this node.
    1.73 +     */
    1.74 +    void *value;
    1.75 +    /**
    1.76 +     * The height of this (sub)-tree.
    1.77 +     */
    1.78 +    size_t height;
    1.79 +    /**
    1.80 +     * Parent node.
    1.81 +     */
    1.82 +    UcxAVLNode *parent;
    1.83 +    /**
    1.84 +     * Root node of left subtree.
    1.85 +     */
    1.86 +    UcxAVLNode *left;
    1.87 +    /**
    1.88 +     * Root node of right subtree.
    1.89 +     */
    1.90 +    UcxAVLNode *right;
    1.91 +};
    1.92 +
    1.93 +/**
    1.94 + * UCX AVL Tree.
    1.95 + */
    1.96 +typedef struct {
    1.97 +    /**
    1.98 +     * The UcxAllocator that shall be used to manage the memory for node data.
    1.99 +     */
   1.100 +    UcxAllocator *allocator;
   1.101 +    /**
   1.102 +     * Root node of the tree.
   1.103 +     */
   1.104 +    UcxAVLNode *root;
   1.105 +    /**
   1.106 +     * Compare function that shall be used to compare the UcxAVLNode keys.
   1.107 +     * @see UcxAVLNode.key
   1.108 +     */
   1.109 +    cmp_func cmpfunc;
   1.110 +    /**
   1.111 +     * Custom user data.
   1.112 +     * This data will also be provided to the cmpfunc.
   1.113 +     */
   1.114 +    void *userdata;
   1.115 +} UcxAVLTree;
   1.116 +
   1.117 +/**
   1.118 + * Initializes a new UcxAVLTree with a default allocator.
   1.119 + * 
   1.120 + * @param cmpfunc the compare function that shall be used
   1.121 + * @return a new UcxAVLTree object
   1.122 + * @see ucx_avl_new_a()
   1.123 + */
   1.124 +UcxAVLTree *ucx_avl_new(cmp_func cmpfunc);
   1.125 +
   1.126 +/**
   1.127 + * Initializes a new UcxAVLTree with the specified allocator.
   1.128 + * 
   1.129 + * The cmpfunc should be capable of comparing two keys within this AVL tree.
   1.130 + * So if you want to use null terminated strings as keys, you could use the
   1.131 + * ucx_strcmp() function here.
   1.132 + * 
   1.133 + * @param cmpfunc the compare function that shall be used
   1.134 + * @param allocator the UcxAllocator that shall be used
   1.135 + * @return a new UcxAVLTree object
   1.136 + */
   1.137 +UcxAVLTree *ucx_avl_new_a(cmp_func cmpfunc, UcxAllocator *allocator);
   1.138 +
   1.139 +/**
   1.140 + * Destroys a UcxAVLTree.
   1.141 + * @param tree the tree to destroy
   1.142 + */
   1.143 +void ucx_avl_free(UcxAVLTree *tree);
   1.144 +
   1.145 +/**
   1.146 + * Macro for initializing a new UcxAVLTree with the default allocator and a
   1.147 + * ucx_ptrcmp() compare function.
   1.148 + * 
   1.149 + * @return a new default UcxAVLTree object
   1.150 + */
   1.151 +#define ucx_avl_default_new() ucx_avl_new_a(ucx_ptrcmp, ucx_default_allocator())
   1.152 +
   1.153 +/**
   1.154 + * Gets the node from the tree, that is associated with the specified key.
   1.155 + * @param tree the UcxAVLTree
   1.156 + * @param key the key
   1.157 + * @return the node (or <code>NULL</code>, if the key is not present)
   1.158 + */
   1.159 +UcxAVLNode *ucx_avl_get_node(UcxAVLTree *tree, intptr_t key);
   1.160 +
   1.161 +/**
   1.162 + * Gets the value from the tree, that is associated with the specified key.
   1.163 + * @param tree the UcxAVLTree
   1.164 + * @param key the key
   1.165 + * @return the value (or <code>NULL</code>, if the key is not present)
   1.166 + */
   1.167 +void *ucx_avl_get(UcxAVLTree *tree, intptr_t key);
   1.168 +
   1.169 +/**
   1.170 + * A mode for #ucx_avl_find_node() with the same behavior as
   1.171 + * #ucx_avl_get_node().
   1.172 + */
   1.173 +#define UCX_AVL_FIND_EXACT         0
   1.174 +/**
   1.175 + * A mode for #ucx_avl_find_node() finding the node whose key is at least
   1.176 + * as large as the specified key.
   1.177 + */
   1.178 +#define UCX_AVL_FIND_LOWER_BOUNDED 1
   1.179 +/**
   1.180 + * A mode for #ucx_avl_find_node() finding the node whose key is at most
   1.181 + * as large as the specified key.
   1.182 + */
   1.183 +#define UCX_AVL_FIND_UPPER_BOUNDED 2
   1.184 +/**
   1.185 + * A mode for #ucx_avl_find_node() finding the node with a key that is as close
   1.186 + * to the specified key as possible. If the key is present, the behavior is
   1.187 + * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
   1.188 + * empty trees.
   1.189 + */
   1.190 +#define UCX_AVL_FIND_CLOSEST       3
   1.191 +
   1.192 +/**
   1.193 + * Finds a node within the tree. The following modes are supported:
   1.194 + * <ul>
   1.195 + * <li>#UCX_AVL_FIND_EXACT: the same behavior as #ucx_avl_get_node()</li>
   1.196 + * <li>#UCX_AVL_FIND_LOWER_BOUNDED: finds the node whose key is at least
   1.197 + * as large as the specified key</li>
   1.198 + * <li>#UCX_AVL_FIND_UPPER_BOUNDED: finds the node whose key is at most
   1.199 + * as large as the specified key</li>
   1.200 + * <li>#UCX_AVL_FIND_CLOSEST: finds the node with a key that is as close to
   1.201 + * the specified key as possible. If the key is present, the behavior is
   1.202 + * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
   1.203 + * empty trees.</li> 
   1.204 + * </ul>
   1.205 + * 
   1.206 + * The distance function provided MUST agree with the compare function of
   1.207 + * the AVL tree.
   1.208 + * 
   1.209 + * @param tree the UcxAVLTree
   1.210 + * @param key the key
   1.211 + * @param dfnc the distance function
   1.212 + * @param mode the find mode
   1.213 + * @return the node (or <code>NULL</code>, if no node can be found)
   1.214 + */
   1.215 +UcxAVLNode *ucx_avl_find_node(UcxAVLTree *tree, intptr_t key,
   1.216 +        distance_func dfnc, int mode);
   1.217 +
   1.218 +/**
   1.219 + * Finds a value within the tree.
   1.220 + * See #ucx_avl_find_node() for details.
   1.221 + * 
   1.222 + * @param tree the UcxAVLTree
   1.223 + * @param key the key
   1.224 + * @param dfnc the distance function
   1.225 + * @param mode the find mode
   1.226 + * @return the value (or <code>NULL</code>, if no value can be found)
   1.227 + */
   1.228 +void *ucx_avl_find(UcxAVLTree *tree, intptr_t key,
   1.229 +        distance_func dfnc, int mode);
   1.230 +
   1.231 +/**
   1.232 + * Puts a key/value pair into the tree.
   1.233 + * 
   1.234 + * Attention: use this function only, if a possible old value does not need
   1.235 + * to be preserved.
   1.236 + * 
   1.237 + * @param tree the UcxAVLTree
   1.238 + * @param key the key
   1.239 + * @param value the new value
   1.240 + * @return zero, if and only if the operation succeeded
   1.241 + */
   1.242 +int ucx_avl_put(UcxAVLTree *tree, intptr_t key, void *value);
   1.243 +
   1.244 +/**
   1.245 + * Puts a key/value pair into the tree.
   1.246 + * 
   1.247 + * This is a secure function which saves the old value to the variable pointed
   1.248 + * at by oldvalue.
   1.249 + * 
   1.250 + * @param tree the UcxAVLTree
   1.251 + * @param key the key
   1.252 + * @param value the new value
   1.253 + * @param oldvalue optional: a pointer to the location where a possible old
   1.254 + * value shall be stored
   1.255 + * @return zero, if and only if the operation succeeded
   1.256 + */
   1.257 +int ucx_avl_put_s(UcxAVLTree *tree, intptr_t key, void *value, void **oldvalue);
   1.258 +
   1.259 +/**
   1.260 + * Removes a node from the AVL tree.
   1.261 + * 
   1.262 + * Note: the specified node is logically removed. The tree implementation
   1.263 + * decides which memory area is freed. In most cases the here provided node
   1.264 + * is freed, so its further use is generally undefined.
   1.265 + * 
   1.266 + * @param tree the UcxAVLTree
   1.267 + * @param node the node to remove
   1.268 + * @return zero, if and only if an element has been removed
   1.269 + */
   1.270 +int ucx_avl_remove_node(UcxAVLTree *tree, UcxAVLNode *node);
   1.271 +
   1.272 +/**
   1.273 + * Removes an element from the AVL tree.
   1.274 + * 
   1.275 + * @param tree the UcxAVLTree
   1.276 + * @param key the key
   1.277 + * @return zero, if and only if an element has been removed
   1.278 + */
   1.279 +int ucx_avl_remove(UcxAVLTree *tree, intptr_t key);
   1.280 +
   1.281 +/**
   1.282 + * Removes an element from the AVL tree.
   1.283 + * 
   1.284 + * This is a secure function which saves the old key and value data from node
   1.285 + * to the variables at the location of oldkey and oldvalue (if specified), so
   1.286 + * they can be freed afterwards (if necessary).
   1.287 + * 
   1.288 + * Note: the returned key in oldkey is possibly not the same as the provided
   1.289 + * key for the lookup (in terms of memory location).
   1.290 + * 
   1.291 + * @param tree the UcxAVLTree
   1.292 + * @param key the key of the element to remove
   1.293 + * @param oldkey optional: a pointer to the location where the old key shall be
   1.294 + * stored
   1.295 + * @param oldvalue optional: a pointer to the location where the old value
   1.296 + * shall be stored
   1.297 + * @return zero, if and only if an element has been removed
   1.298 + */
   1.299 +int ucx_avl_remove_s(UcxAVLTree *tree, intptr_t key,
   1.300 +        intptr_t *oldkey, void **oldvalue);
   1.301 +
   1.302 +/**
   1.303 + * Counts the nodes in the specified UcxAVLTree.
   1.304 + * @param tree the AVL tree
   1.305 + * @return the node count
   1.306 + */
   1.307 +size_t ucx_avl_count(UcxAVLTree *tree);
   1.308 +
   1.309 +/**
   1.310 + * Finds the in-order predecessor of the given node.
   1.311 + * @param node an AVL node
   1.312 + * @return the in-order predecessor of the given node, or <code>NULL</code> if
   1.313 + * the given node is the in-order minimum
   1.314 + */
   1.315 +UcxAVLNode* ucx_avl_pred(UcxAVLNode* node);
   1.316 +
   1.317 +/**
   1.318 + * Finds the in-order successor of the given node.
   1.319 + * @param node an AVL node
   1.320 + * @return the in-order successor of the given node, or <code>NULL</code> if
   1.321 + * the given node is the in-order maximum
   1.322 + */
   1.323 +UcxAVLNode* ucx_avl_succ(UcxAVLNode* node);
   1.324 +
   1.325 +#ifdef	__cplusplus
   1.326 +}
   1.327 +#endif
   1.328 +
   1.329 +#endif	/* UCX_AVL_H */
   1.330 +

mercurial