00001 /* EGlib "Efficient General Library" provides some basic structures and 00002 * algorithms commons in many optimization algorithms. 00003 * 00004 * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea. 00005 * 00006 * This library is free software; you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by the 00008 * Free Software Foundation; either version 2.1 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, but 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00013 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this library; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 * */ 00020 /* ========================================================================= */ 00021 /** @defgroup EGeBTree EGeBTree 00022 * 00023 * Here we define a minimal implementation of binary trees, using the philosophy 00024 * of embeded structures. Operations as adding nodes (in any position of the 00025 * tree), deleting nodes, splicing trees, and separating sub-trees are performed 00026 * in O(1) time. To obtain this running time information such as depth is not 00027 * stored in the nodes of the tree. 00028 * 00029 * -2005-07-08 00030 * - First Implementation 00031 * */ 00032 /** @file 00033 * @ingroup EGeBTree */ 00034 /** @addtogroup EGeBTree */ 00035 /** @{ 00036 * @example eg_ebtree.ex.c 00037 * This is a simple example for the usage of binary trees as implemented in @ref 00038 * EGeBTree. */ 00039 /* ========================================================================= */ 00040 #ifndef __EG_EBTREE_H__ 00041 #define __EG_EBTREE_H__ 00042 #include "eg_macros.h" 00043 00044 /* ========================================================================= */ 00045 /** @brief Parent index */ 00046 #define EG_EBTREE_PARENT 0 00047 00048 /* ========================================================================= */ 00049 /** @brief Left Child Index */ 00050 #define EG_EBTREE_LEFT 1 00051 00052 /* ========================================================================= */ 00053 /** @brief Right Child Index */ 00054 #define EG_EBTREE_RIGHT 2 00055 00056 /* ========================================================================= */ 00057 /** @brief Basic structure of a tree node, note that a node in a tree is in 00058 * itself a (sub)tree. */ 00059 typedef struct EGeBTree_t 00060 { 00061 struct EGeBTree_t *cn[3]; /**< This array contains three pointers, in 00062 position #EG_EBTREE_PARENT the link to the 00063 parent of this node, in position 00064 #EG_EBTREE_LEFT the link to the left child, and 00065 in #EG_EBTREE_RIGHT the link to the right 00066 child for this node. If any of this pointers 00067 is NULL, then the link does not exists. In 00068 particular a leaf is a node with both child 00069 links set to NULL, and the root of a tree 00070 is the node whose parent link is NULL. */ 00071 } 00072 EGeBTree_t; 00073 00074 /* ========================================================================= */ 00075 /** @brief Initialize a tree structure. It let it as a tree containing only 00076 * itself. and allocate any internal memory (not allocated by the user). 00077 * @param tn tree to initialize. 00078 * @note Note that the definition of #EGeBTree_t does not need to initialize any 00079 * memory, and basically reset and init do exactly the same, while clear do 00080 * nothing. */ 00081 #define EGeBTreeInit(tn) (*(tn) = (EGeBTree_t){{0,0,0}}) 00082 00083 /* ========================================================================= */ 00084 /** @brief Let a tree just as after an init call. 00085 * @param tn tree to reset. 00086 * @note Note that this macro is provided onll for completeness, because there 00087 * is no need for it. 00088 * */ 00089 #define EGeBTreeReset(tn) EGeBTreeInit(tn) 00090 00091 /* ========================================================================= */ 00092 /** @brief Free any internal memory (not allocated by the user) related to this 00093 * structure. 00094 * @param tn tree to be cleared. 00095 * @note Note that this function is not really needed, it is provided for 00096 * completness, but is defined as nothing. */ 00097 #define EGeBTreeClear(tn) 00098 00099 /* ========================================================================= */ 00100 /** @brief Add a left child to a node in a tree. 00101 * @param parent node to wich we will add a left child 00102 * @param child node to be a left child 00103 * @return zero on success, non zero otherwise. 00104 * */ 00105 #define EGeBTreeAddLeft(parent,child) ({\ 00106 EGeBTree_t*const __EGeparent = (parent);\ 00107 EGeBTree_t*const __EGechild = (child);\ 00108 __EGeparent->cn[EG_EBTREE_LEFT] ? (fprintf(stderr,"Can't add left child to "#parent" because it already has a left child, in %s:%s:%d\n",__func__,__FILE__,__LINE__),1): (__EGeparent->cn[EG_EBTREE_LEFT] = __EGechild, __EGechild->cn[EG_EBTREE_PARENT] = __EGeparent, 0);}) 00109 00110 /* ========================================================================= */ 00111 /** @brief Add a right child to a node in a tree. 00112 * @param parent node to wich we will add a right child 00113 * @param child node to be a right child 00114 * @return zero on success, non zero otherwise. 00115 * */ 00116 #define EGeBTreeAddRight(parent,child) ({\ 00117 EGeBTree_t*const __EGeparent = (parent);\ 00118 EGeBTree_t*const __EGechild = (child);\ 00119 __EGeparent->cn[EG_EBTREE_RIGHT] ? (fprintf(stderr,"Can't add right child to "#parent" because it already has a right child, in %s:%s:%d\n",__func__,__FILE__,__LINE__),1): (__EGeparent->cn[EG_EBTREE_RIGHT] = __EGechild, __EGechild->cn[EG_EBTREE_PARENT] = __EGeparent, 0);}) 00120 00121 /* ========================================================================= */ 00122 /** @return a pointer to the parent of the given node, if NULL, then this node 00123 * is the root node of the tree. 00124 * @param member node for wich we are looking for the father. 00125 * @return pointer to the parent node in the tree. 00126 * */ 00127 #define EGeBTreeGetParent(member) ((member)->cn[EG_EBTREE_PARENT]) 00128 00129 /* ========================================================================= */ 00130 /** @return a pointer to the left child of the given node, if NULL, then this 00131 * node don;t have a left child 00132 * @param member node for wich we are looking for the left child. 00133 * @return pointer to the left child node in the tree. 00134 * */ 00135 #define EGeBTreeGetLeft(member) ((member)->cn[EG_EBTREE_LEFT]) 00136 00137 /* ========================================================================= */ 00138 /** @return a pointer to the right child of the given node, if NULL, then this 00139 * node don;t have a right child 00140 * @param member node for wich we are looking for the right child. 00141 * @return pointer to the right child node in the tree. 00142 * */ 00143 #define EGeBTreeGetRight(member) ((member)->cn[EG_EBTREE_RIGHT]) 00144 00145 /* ========================================================================= */ 00146 /** @brief return the root of the tree containing the given tree node. 00147 * @param member node for wich we are looking for the tree-root. 00148 * @return pointer to the root of the tree containing the given node. 00149 * */ 00150 #define EGeBTreeGetRoot(member) ({\ 00151 EGeBTree_t*__EGeroot = (member);\ 00152 while(__EGeroot->cn[EG_EBTREE_PARENT]) \ 00153 __EGeroot = __EGeroot->cn[EG_EBTREE_PARENT];\ 00154 __EGeroot;}) 00155 00156 /* ========================================================================= */ 00157 /** @brief Replace a node in a tree. 00158 * @param old node to be replaced. 00159 * @param replacement node to be used as replacement. 00160 * @return zero on success, non-zero otherwise. 00161 * */ 00162 #define EGeBTreeReplace(old,replacement) ({\ 00163 EGeBTree_t*const __EGeold = (old);\ 00164 EGeBTree_t*const __EGenew = (replacement);\ 00165 EGeBTree_t*const __EGepar = __EGeold->cn[EG_EBTREE_PARENT];\ 00166 EGeBTree_t*const __EGelft = __EGeold->cn[EG_EBTREE_LEFT];\ 00167 EGeBTree_t*const __EGergt = __EGeold->cn[EG_EBTREE_RIGHT];\ 00168 *__EGenew = *__EGeold;\ 00169 if(__EGepar)\ 00170 {\ 00171 if(__EGepar->cn[EG_EBTREE_LEFT] == __EGeold)\ 00172 __EGepar->cn[EG_EBTREE_LEFT] = __EGenew;\ 00173 else __EGepar->cn[EG_EBTREE_RIGHT] = __EGenew;\ 00174 }\ 00175 if(__EGelft) __EGelft->cn[EG_EBTREE_PARENT] = __EGenew;\ 00176 if(__EGergt) __EGergt->cn[EG_EBTREE_PARENT] = __EGenew;\ 00177 0;}) 00178 00179 /* ========================================================================= */ 00180 /** @brief return the successor of the given node in it's tree according to the 00181 * in-order ordering. 00182 * @param node element for wich we want the successor. 00183 * @return pointer to the successor, if NULL is returned, then there is no 00184 * successor for the given node. 00185 * @note The in-order considered here is the one depicted in the next figure: 00186 * \f[ 00187 \psset{unit=1cm,arrows=->} 00188 \begin{pspicture}(-1,-1)(7,3) 00189 \rput(0,0){\circlenode{a}{1}} 00190 \rput(1,1){\circlenode{b}{2}} 00191 \rput(2,0){\circlenode{c}{3}} 00192 \rput(3,2){\circlenode{d}{4}} 00193 \rput(4,0){\circlenode{e}{5}} 00194 \rput(5,1){\circlenode{f}{6}} 00195 \rput(6,0){\circlenode{g}{7}} 00196 \ncline{b}{a} 00197 \ncline{b}{c} 00198 \ncline{d}{b} 00199 \ncline{d}{f} 00200 \ncline{f}{e} 00201 \ncline{f}{g} 00202 \end{pspicture} 00203 \f] In this figure the numbers in the nodes represent the in-order order. */ 00204 #define EGeBTreeGetNext(node) ({\ 00205 EGeBTree_t* __EGexn = (node);\ 00206 EGeBTree_t* __EGecn = __EGexn->cn[EG_EBTREE_RIGHT];\ 00207 if(__EGecn) while(__EGecn->cn[EG_EBTREE_LEFT])\ 00208 __EGecn = __EGecn->cn[EG_EBTREE_LEFT];\ 00209 else do __EGecn = __EGexn->cn[EG_EBTREE_PARENT]; while(__EGecn && \ 00210 __EGecn->cn[EG_EBTREE_RIGHT] == __EGexn && (__EGexn = __EGecn));\ 00211 __EGecn;}) 00212 00213 /* ========================================================================= */ 00214 /** @brief return the predecesor of the given node in it's tree according to 00215 * the in-order ordering. 00216 * @param node element for wich we want the predecesor. 00217 * @return pointer to the predecesor, if NULL is returned, then there is no 00218 * predecesor for the given node. 00219 * @note The in-order considered here is the one depicted in the next figure: 00220 * \f[ 00221 \psset{unit=1cm,arrows=->} 00222 \begin{pspicture}(-1,-1)(7,3) 00223 \rput(0,0){\circlenode{a}{1}} 00224 \rput(1,1){\circlenode{b}{2}} 00225 \rput(2,0){\circlenode{c}{3}} 00226 \rput(3,2){\circlenode{d}{4}} 00227 \rput(4,0){\circlenode{e}{5}} 00228 \rput(5,1){\circlenode{f}{6}} 00229 \rput(6,0){\circlenode{g}{7}} 00230 \ncline{b}{a} 00231 \ncline{b}{c} 00232 \ncline{d}{b} 00233 \ncline{d}{f} 00234 \ncline{f}{e} 00235 \ncline{f}{g} 00236 \end{pspicture} 00237 \f] In this figure the numbers in the nodes represent the in-order order. */ 00238 #define EGeBTreeGetPrev(node) ({\ 00239 EGeBTree_t* __EGexn = (node);\ 00240 EGeBTree_t* __EGecn = __EGexn->cn[EG_EBTREE_LEFT];\ 00241 if(__EGecn) while(__EGecn->cn[EG_EBTREE_RIGHT])\ 00242 __EGecn = __EGecn->cn[EG_EBTREE_RIGHT];\ 00243 else do __EGecn = __EGexn->cn[EG_EBTREE_PARENT]; while(__EGecn && \ 00244 __EGecn->cn[EG_EBTREE_LEFT] == __EGexn && (__EGexn = __EGecn));\ 00245 __EGecn;}) 00246 00247 /* ========================================================================= */ 00248 /** @brief return the first node in the (sub-)tree (according to the in-order). 00249 * @param node pointer to a node of the tree. 00250 * @return first node in the tree. 00251 * */ 00252 #define EGeBTreeGetFirst(node) ({\ 00253 EGeBTree_t* __EGecn = (node);\ 00254 while(__EGecn->cn[EG_EBTREE_LEFT]) __EGecn = __EGecn->cn[EG_EBTREE_LEFT];\ 00255 __EGecn;}) 00256 00257 /* ========================================================================= */ 00258 /** @brief return the last node in the (sub-)tree (according to the in-order). 00259 * @param node pointer to a node of the tree. 00260 * @return last node in the tree. 00261 * */ 00262 #define EGeBTreeGetLast(node) ({\ 00263 EGeBTree_t* __EGecn = (node);\ 00264 while(__EGecn->cn[EG_EBTREE_RIGHT]) __EGecn = __EGecn->cn[EG_EBTREE_RIGHT];\ 00265 __EGecn;}) 00266 00267 /* ========================================================================= */ 00268 /** @brief Erase a leaf node from a tree. 00269 * @param leaf node to be erased from the tree. 00270 * @return zero on success, non-zero otherwise, a failure means that the given 00271 * node wasn't a leaf in the tree. 00272 * */ 00273 #define EGeBTreeDel(leaf) ({\ 00274 EGeBTree_t*const __EGelf = (leaf);\ 00275 EGeBTree_t*const __EGepar = __EGelf->cn[EG_EBTREE_PARENT];\ 00276 int __rval = 0;\ 00277 if(__EGelf->cn[EG_EBTREE_LEFT] || __EGelf->cn[EG_EBTREE_RIGHT]) __rval = 1;\ 00278 else if(__EGepar)\ 00279 {\ 00280 if(__EGepar->cn[EG_EBTREE_LEFT] == __EGelf) \ 00281 __EGepar->cn[EG_EBTREE_LEFT] = 0;\ 00282 else __EGepar->cn[EG_EBTREE_RIGHT] = 0;\ 00283 }\ 00284 __rval;}) 00285 00286 /* ========================================================================= */ 00287 /** @brief Cut the given node from the tree containing it (and so create a 00288 * sub-tree). 00289 * @param member 00290 * @return zero on success, non-zero otherwise. 00291 * */ 00292 #define EGeBTreeCut(member) ({\ 00293 EGeBTree_t*const __EGeroot = (member);\ 00294 EGeBTree_t*const __EGepar = __EGeroot->cn[EG_EBTREE_PARENT];\ 00295 if(__EGepar) \ 00296 {\ 00297 __EGeroot->cn[EG_EBTREE_PARENT] = 0; \ 00298 if(__EGepar->cn[EG_EBTREE_LEFT] == __EGeroot)\ 00299 __EGepar->cn[EG_EBTREE_LEFT] = 0;\ 00300 else __EGepar->cn[EG_EBTREE_RIGHT] = 0;\ 00301 }\ 00302 0;}) 00303 00304 /* ========================================================================= */ 00305 /** @} */ 00306 #endif
1.4.5