| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 | /* MACRO-CODED FAST FIXED AVL TREES IMPLEMENTATION IN C              *//* COPYRIGHT (C) 1998 VALERY SHCHEDRIN                               *//* IT IS DISTRIBUTED UNDER GLPL (GNU GENERAL LIBRARY PUBLIC LICENSE) *//* * Manuel Novoa III       Jan 2001 * * Modified to decrease object size. *   Tree balancing is now done in a fuction rather than inline. *   Removed common code in balance by use of a goto. *   Added macro Avl_Tree_no_replace since ptrs_replace was not used. *   Prepended may symbols with "__" for possible conversion to extern. */#define __Avl_balance_proto(objname, pr, root) \  static int __Avl_##objname##pr##balance(objname **root) \  { \    objname *p; \    int ht_changed; \    p = *root; \    if (p->bal_##pr < -1) \    { \      if (p->l_##pr->bal_##pr == 1) \      { \	objname *pp; \	pp=p->l_##pr; *root=p->l_##pr->r_##pr; p->l_##pr = (*root)->r_##pr; \	(*root)->r_##pr = p; pp->r_##pr = (*root)->l_##pr; \	p = *root; p->l_##pr = pp; \    goto pr_common_ht_changed; \      } \      else \      { \	ht_changed = (p->l_##pr ->bal_##pr)?1:0; \	*root = p->l_##pr ; \	p->l_##pr = (*root)->r_##pr ; (*root)->r_##pr = p; \	p->bal_##pr = - (++((*root)->bal_##pr )); \      } \    } \    else if (p->bal_##pr > 1) \    { \      if (p->r_##pr->bal_##pr == -1) \      { \	objname *pp; \	pp=p->r_##pr ; *root=p->r_##pr ->l_##pr ; p->r_##pr =(*root)->l_##pr ; \	(*root)->l_##pr = p; pp->l_##pr = (*root)->r_##pr ; \	p = *root; p->r_##pr = pp; \    pr_common_ht_changed: \	if (p->bal_##pr > 0) p->l_##pr ->bal_##pr = -p->bal_##pr ; \	else p->l_##pr ->bal_##pr = 0; \	if (p->bal_##pr < 0) p->r_##pr ->bal_##pr = -p->bal_##pr ; \	else p->r_##pr ->bal_##pr = 0; \	p->bal_##pr = 0; \	ht_changed = 1; \      } \      else \      { \	ht_changed = (p->r_##pr ->bal_##pr)?1:0; \	*root = p->r_##pr ; \	p->r_##pr = (*root)->l_##pr ; (*root)->l_##pr = p; \	p->bal_##pr = - (--((*root)->bal_##pr )); \      } \    } else ht_changed = 0; \   return ht_changed; \  }#define balance(objname, pr, root) \  __Avl_##objname##pr##balance(root)#define __Avl_r_insert_proto(objname, pr, COMPARE) \  static int __Avl_##objname##pr##_r_insert(objname **root) \  { \    int i; /* height increase */ \    if (!*root) \    { \      *root = __Avl_##objname##pr##_new_node; \      __Avl_##objname##pr##_new_node = NULL; \      return 1; \    } \    COMPARE(i, __Avl_##objname##pr##_new_node, *root); \    \    if (i < 0) \    { /* insert into the left subtree */ \      i = -__Avl_##objname##pr##_r_insert(&((*root)->l_##pr)); \      if (__Avl_##objname##pr##_new_node != NULL) return 0; /* already there */ \    } \    else if (i > 0) \    { /* insert into the right subtree */ \      i = __Avl_##objname##pr##_r_insert(&((*root)->r_##pr)); \      if (__Avl_##objname##pr##_new_node != NULL) return 0; /* already there */ \    } \    else \    { /* found */ \      __Avl_##objname##pr##_new_node = *root; \      return 0; \    } \    if (!i) return 0; \    (*root)->bal_##pr += i; /* update balance factor */ \    if ((*root)->bal_##pr) \    { \      return 1 - balance(objname,pr,root); \    } \    else return 0; \  }#define __Avl_r_delete_proto(objname,pr,COMPARE) \  static int __Avl_##objname##pr##_r_delete(objname **root) \  { \    int i; /* height decrease */ \    \    if (!*root) return 0; /* not found */ \    \    COMPARE(i, __Avl_##objname##pr##_new_node, *root); \    \    if (i < 0) \      i = -__Avl_##objname##pr##_r_delete(&((*root)->l_##pr)); \    else if (i > 0) \      i =  __Avl_##objname##pr##_r_delete(&((*root)->r_##pr)); \    else \    { \      if (!(*root)->l_##pr) \      { \	*root = (*root)->r_##pr; \	return 1; \      } \      else if (!(*root)->r_##pr) \      { \	*root = (*root)->l_##pr; \	return 1; \      } \      else \      { \	i = __Avl_##objname##pr##_r_delfix(&((*root)->r_##pr)); \	__Avl_##objname##pr##_new_node->l_##pr = (*root)->l_##pr; \	__Avl_##objname##pr##_new_node->r_##pr = (*root)->r_##pr; \	__Avl_##objname##pr##_new_node->bal_##pr = (*root)->bal_##pr; \	*root = __Avl_##objname##pr##_new_node; \      } \    } \    if (!i) return 0; \    (*root)->bal_##pr -= i; \    if ((*root)->bal_##pr) \    { \      return balance(objname,pr,root); \    } \    return 1; \  }#define __Avl_r_delfix_proto(objname,pr) \  static int __Avl_##objname##pr##_r_delfix(objname **root) \  { \    int i; /* height decrease */ \    \    if (!(*root)->l_##pr) \    { \      __Avl_##objname##pr##_new_node = *root; \      *root = (*root)->r_##pr; \      return 1; \    } \    i = -__Avl_##objname##pr##_r_delfix(&((*root)->l_##pr)); \    if (!i) return 0; \    (*root)->bal_##pr -= i; \    if ((*root)->bal_##pr) \    { \      return balance(objname,pr,root); \    } \    return 1; \  }#define __Avl_ins_proto(alias,objname,pr) \  objname *__##alias##_ins(objname *data) \  { \    __Avl_##objname##pr##_new_node = data; \    (data)->l_##pr = NULL; \    (data)->r_##pr = NULL; \    (data)->bal_##pr = 0; \    __Avl_##objname##pr##_r_insert(&__Avl_##objname##pr##_tree); \    if (__Avl_##objname##pr##_new_node) \      return __Avl_##objname##pr##_new_node; \    return NULL; \  }#define __Avl_del_proto(alias,objname,pr) \  void __##alias##_del(objname *data) \  { \    __Avl_##objname##pr##_new_node = data; \    __Avl_##objname##pr##_r_delete(&__Avl_##objname##pr##_tree); \  }#define __Avl_replace_proto(alias,objname,pr,COMPARE) \  void __##alias##_replace(objname *data) \  { \    objname **p = &__Avl_##objname##pr##_tree; \    int cmp; \    while (*p) \    { \      COMPARE(cmp, data, *p); \      if (cmp < 0) \	p = &((*p)->l_##pr); \      else if (cmp > 0) \	p = &((*p)->r_##pr); \      else \      { \	(data)->l_##pr = (*p)->l_##pr; \	(data)->r_##pr = (*p)->r_##pr; \	(data)->bal_##pr = (*p)->bal_##pr; \	*p = data; \	return; \      } \    } \  }#define Avl_Root(objname,pr) __Avl_##objname##pr##_tree#define Avl_Tree_no_replace(alias,objname,pr,COMPARE) \objname *__Avl_##objname##pr##_tree = NULL; \static objname *__Avl_##objname##pr##_new_node; \__Avl_balance_proto(objname, pr, root) \__Avl_r_insert_proto(objname,pr,COMPARE) \__Avl_r_delfix_proto(objname,pr) \__Avl_r_delete_proto(objname,pr,COMPARE) \__Avl_ins_proto(alias,objname,pr) \__Avl_del_proto(alias,objname,pr)#define Avl_Tree(alias,objname,pr,COMPARE) \Avl_Tree_no_replace(alias,objname,pr,COMPARE) \__Avl_replace_proto(alias,objname,pr,COMPARE)
 |