eg_ebtree.h

Go to the documentation of this file.
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

Generated on Mon Jan 30 08:48:53 2006 for EGlib by  doxygen 1.4.5