9 #ifndef __ZEDA_TREE_H__ 10 #define __ZEDA_TREE_H__ 41 #define zTreeClass(node_t,data_t) \ 42 typedef struct __##node_t{\ 43 struct __##node_t *parent;\ 44 struct __##node_t *child[2];\ 49 __EXPORT node_t *node_t##Init(node_t *node);\ 50 __EXPORT void node_t##Destroy(node_t *tree);\ 51 __EXPORT node_t *node_t##NodeAlloc(data_t *val) 53 #define zTreeClassMethod(node_t,data_t,init,destroy) \ 54 static data_t *(* _##node_t##DataInit)(data_t *) = init;\ 55 static void (* _##node_t##DataDestroy)(data_t *) = destroy;\ 57 node_t *node_t##Init(node_t *node){\ 58 if( _##node_t##DataInit ) _##node_t##DataInit( &(node)->data );\ 59 node->parent = node->child[0] = node->child[1] = NULL;\ 64 static void __##node_t##NodeDestroy(node_t *node){\ 66 __##node_t##NodeDestroy( node->child[0] );\ 68 __##node_t##NodeDestroy( node->child[1] );\ 69 if( _##node_t##DataDestroy ) _##node_t##DataDestroy( &(node)->data );\ 73 void node_t##Destroy(node_t *tree){\ 75 __##node_t##NodeDestroy( tree->child[0] );\ 76 node_t##Init( tree );\ 79 node_t *node_t##NodeAlloc(data_t *val){\ 81 if( !( node = zAlloc( node_t, 1 ) ) ){\ 85 node_t##Init( node );\ 86 memcpy( &node->data, val, sizeof(data_t) );\ 90 #define zHeapClass(node_t,data_t) \ 91 zTreeClass(node_t,data_t); \ 92 __EXPORT node_t *node_t##AddComplete(node_t *tree, data_t *val);\ 93 __EXPORT node_t *node_t##UpHeap(node_t *tree, node_t *node, int (* cmp)(node_t*,node_t*,void*), void *util);\ 94 __EXPORT node_t *node_t##AddHeap(node_t *tree, data_t *val, int (* cmp)(node_t*,node_t*,void*), void *util);\ 95 __EXPORT node_t *node_t##DownHeap(node_t *node, int (* cmp)(node_t*,node_t*,void*), void *util);\ 96 __EXPORT node_t *node_t##DeleteHeap(node_t *tree, int (* cmp)(node_t*,node_t*,void*), void *util);\ 97 __EXPORT void node_t##Heapify(node_t *tree, int (* cmp)(node_t*,node_t*,void*), void *util) 99 #define zHeapClassMethod(node_t,data_t,init,destroy) \ 100 zTreeClassMethod(node_t,data_t,init,destroy) \ 101 static void __##node_t##BindParentChild(node_t *parent, int id, node_t *child){\ 102 if( ( parent->child[id] = child ) ) child->parent = parent;\ 105 static void __##node_t##NodeSwapHeap(node_t *node, int cid){\ 106 node_t *parent, *tmp;\ 108 parent = node->parent;\ 109 id = _zTreeParentID( node );\ 110 __##node_t##BindParentChild( parent, id, node->child[cid] );\ 111 __##node_t##BindParentChild( node, cid, node->child[cid]->child[cid] );\ 112 __##node_t##BindParentChild( parent->child[id], cid, node );\ 113 tmp = node->child[1-cid];\ 114 __##node_t##BindParentChild( node, 1-cid, parent->child[id]->child[1-cid] );\ 115 __##node_t##BindParentChild( parent->child[id], 1-cid, tmp );\ 118 node_t *node_t##AddComplete(node_t *tree, data_t *val){\ 119 node_t *node, *np_new;\ 121 if( !( np_new = node_t##NodeAlloc( val ) ) ) return NULL;\ 122 if( ++tree->size == 1 ){\ 123 __##node_t##BindParentChild( tree, 0, np_new );\ 124 return tree->child[0];\ 126 _zTreeInitHeapMask( tree, &mask );\ 127 for( node=tree->child[0]; ; node=node->child[cid], mask>>=1 ){\ 128 cid = mask & tree->size ? 1 : 0;\ 129 if( mask == 1 ) break;\ 131 __##node_t##BindParentChild( node, cid, np_new );\ 135 node_t *node_t##UpHeap(node_t *tree, node_t *node, int (* cmp)(node_t*,node_t*,void*), void *util){\ 136 while( node->parent != tree && !cmp( node->parent, node, util ) )\ 137 __##node_t##NodeSwapHeap( node->parent, _zTreeParentID( node ) );\ 141 node_t *node_t##AddHeap(node_t *tree, data_t *val, int (* cmp)(node_t*,node_t*,void*), void *util){\ 142 return node_t##UpHeap( tree, node_t##AddComplete( tree, val ), cmp, util );\ 145 node_t *node_t##DownHeap(node_t *node, int (* cmp)(node_t*,node_t*,void*), void *util){\ 147 while( node->child[0] ){\ 148 cid = !node->child[1] ? 0 : ( cmp( node->child[0], node->child[1], util ) ? 0 : 1 );\ 149 if( cmp( node, node->child[cid], util ) ) break;\ 150 __##node_t##NodeSwapHeap( node, cid );\ 155 node_t *node_t##DeleteHeap(node_t *tree, int (* cmp)(node_t*,node_t*,void*), void *util){\ 158 _zTreeInitHeapMask( tree, &mask );\ 159 for( np=tree->child[0]; np; mask>>=1, np=np->child[cid] ){\ 160 cid = mask & tree->size ? 1 : 0;\ 161 if( mask == 1 ) break;\ 163 ret = tree->child[0];\ 165 tree->child[0] = NULL;\ 166 } else if( np->child[cid] ){\ 167 __##node_t##BindParentChild( tree, 0, np->child[cid] );\ 168 np->child[cid] = NULL;\ 169 __##node_t##BindParentChild( tree->child[0], 0, ret->child[0] );\ 170 __##node_t##BindParentChild( tree->child[0], 1, ret->child[1] );\ 171 node_t##DownHeap( tree->child[0], cmp, util );\ 173 ret->parent = ret->child[0] = ret->child[1] = NULL;\ 178 static void __##node_t##Heapify(node_t *tree, int (* cmp)(node_t*,node_t*,void*), void *util){\ 179 if( zTreeIsLeaf( tree ) ) return;\ 180 if( tree->child[0] ) __##node_t##Heapify( tree->child[0], cmp, util );\ 181 if( tree->child[1] ) __##node_t##Heapify( tree->child[1], cmp, util );\ 182 node_t##DownHeap( tree, cmp, util );\ 185 void node_t##Heapify(node_t *tree, int (* cmp)(node_t*,node_t*,void*), void *util){\ 186 if( zTreeIsEmpty( tree ) ) return;\ 187 __##node_t##Heapify( tree->child[0], cmp, util );\ 190 #define zTreeIsEmpty(t) ( (t)->size == 0 ) 191 #define zTreeIsLeaf(t) ( !(t)->child[0] && !(t)->child[1] ) 193 #define _zTreeParentID(n) ( (n)->parent->child[0] == (n) ? 0 : ( (n)->parent->child[1] == (n) ? 1 : -1 ) ) 195 #define _zTreeInitHeapMask(t,mask) do{\ 196 *(mask) = 1 << ( sizeof(int)*8 - 2 );\ 197 while( !( *(mask) & (t)->size ) ) *(mask) >>= 1;\ 201 #define zTreeInit(node_t,node) node_t##Init( node ) 202 #define zTreeDestroy(node_t,tree) node_t##Destroy( tree ) 203 #define zTreeNodeAlloc(node_t,val) node_t##NodeAlloc( val ) 204 #define zTreeAddComplete(node_t,tree,val) node_t##AddComplete( tree, val ) 205 #define zTreeUpHeap(node_t,tree,node,cmp,util) node_t##UpHeap( tree, node, cmp, util ) 206 #define zTreeAddHeap(node_t,tree,val,cmp,util) node_t##AddHeap( tree, val, cmp, util ) 207 #define zTreeDownHeap(node_t,node,cmp,util) node_t##DownHeap( node, cmp, util ) 208 #define zTreeDeleteHeap(node_t,tree,cmp,util) node_t##DeleteHeap( tree, cmp, util ) 209 #define zTreeHeapify(node_t,tree,cmp,util) node_t##Heapify( tree, cmp, util ) #define __END_DECLS
Definition: zeda_defs.h:30
#define __BEGIN_DECLS
Definition: zeda_defs.h:26