turbo_avl.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 710 行 · 第 1/2 页
C
710 行
/* turbo_avl.c */#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/dsap/common/RCS/turbo_avl.c,v 9.0 1992/06/16 12:12:39 isode Rel $";#endif/* * $Header: /xtel/isode/isode/dsap/common/RCS/turbo_avl.c,v 9.0 1992/06/16 12:12:39 isode Rel $ * * * $Log: turbo_avl.c,v $ * Revision 9.0 1992/06/16 12:12:39 isode * Release 8.0 * *//* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */#include <sys/types.h>#include "manifest.h"#include "quipu/util.h"#include "quipu/attr.h"#include "quipu/entry.h"#include "quipu/turbo.h"extern LLog * log_dsap;#define ROTATERIGHT(x) { \ Avlnode *tmp;\ if ( *x == NULL || (*x)->avl_left == NULL ) {\ (void) printf("RR error\n"); exit(1); \ }\ tmp = (*x)->avl_left;\ (*x)->avl_left = tmp->avl_right;\ tmp->avl_right = *x;\ *x = tmp;\}#define ROTATELEFT(x) { \ Avlnode *tmp;\ if ( *x == NULL || (*x)->avl_right == NULL ) {\ (void) printf("RL error\n"); exit(1); \ }\ tmp = (*x)->avl_right;\ (*x)->avl_right = tmp->avl_left;\ tmp->avl_left = *x;\ *x = tmp;\}static ravl_insert( iroot, data, taller, fcmp, fdup, depth )Avlnode **iroot;caddr_t data;int *taller;IFP fcmp; /* comparison function */IFP fdup; /* function to call for duplicates */int depth;{ int rc, cmp, tallersub; Avlnode *l, *r; if ( *iroot == 0 ) { *iroot = ( Avlnode * ) malloc( sizeof( Avlnode ) ); (*iroot)->avl_left = 0; (*iroot)->avl_right = 0; (*iroot)->avl_bf = 0; (*iroot)->avl_data = data; *taller = 1; return( OK ); } cmp = (*fcmp)( data, (*iroot)->avl_data ); /* equal - duplicate name */ if ( cmp == 0 ) { *taller = 0; return( (*fdup)( (*iroot)->avl_data, data ) ); } /* go right */ else if ( cmp > 0 ) { rc = ravl_insert( &((*iroot)->avl_right), data, &tallersub, fcmp, fdup, depth ); if ( tallersub ) switch ( (*iroot)->avl_bf ) { case LH : /* left high - balance is restored */ (*iroot)->avl_bf = EH; *taller = 0; break; case EH : /* equal height - now right heavy */ (*iroot)->avl_bf = RH; *taller = 1; break; case RH : /* right heavy to start - right balance */ r = (*iroot)->avl_right; switch ( r->avl_bf ) { case LH : /* double rotation left */ l = r->avl_left; switch ( l->avl_bf ) { case LH : (*iroot)->avl_bf = EH; r->avl_bf = RH; break; case EH : (*iroot)->avl_bf = EH; r->avl_bf = EH; break; case RH : (*iroot)->avl_bf = LH; r->avl_bf = EH; break; } l->avl_bf = EH; ROTATERIGHT( (&r) ) (*iroot)->avl_right = r; ROTATELEFT( iroot ) *taller = 0; break; case EH : /* This should never happen */ break; case RH : /* single rotation left */ (*iroot)->avl_bf = EH; r->avl_bf = EH; ROTATELEFT( iroot ) *taller = 0; break; } break; } else *taller = 0; } /* go left */ else { rc = ravl_insert( &((*iroot)->avl_left), data, &tallersub, fcmp, fdup, depth ); if ( tallersub ) switch ( (*iroot)->avl_bf ) { case LH : /* left high to start - left balance */ l = (*iroot)->avl_left; switch ( l->avl_bf ) { case LH : /* single rotation right */ (*iroot)->avl_bf = EH; l->avl_bf = EH; ROTATERIGHT( iroot ) *taller = 0; break; case EH : /* this should never happen */ break; case RH : /* double rotation right */ r = l->avl_right; switch ( r->avl_bf ) { case LH : (*iroot)->avl_bf = RH; l->avl_bf = EH; break; case EH : (*iroot)->avl_bf = EH; l->avl_bf = EH; break; case RH : (*iroot)->avl_bf = EH; l->avl_bf = LH; break; } r->avl_bf = EH; ROTATELEFT( (&l) ) (*iroot)->avl_left = l; ROTATERIGHT( iroot ) *taller = 0; break; } break; case EH : /* equal height - now left heavy */ (*iroot)->avl_bf = LH; *taller = 1; break; case RH : /* right high - balance is restored */ (*iroot)->avl_bf = EH; *taller = 0; break; } else *taller = 0; } return( rc );}/* * avl_insert -- insert a node containing data data into the avl tree * with root root. fcmp is a function to call to compare the data portion * of two nodes. it should take two arguments and return <, >, or == 0, * depending on whether its first argument is <, >, or == its second * argument (like strcmp, e.g.). fdup is a function to call when a duplicate * node is inserted. it should return OK, or NOTOK and its return value * will be the return value from avl_insert in the case of a duplicate node. * the function will be called with the original node's data as its first * argument and with the incoming duplicate node's data as its second * argument. this could be used, for example, to keep a count with each * node. * * NOTE: this routine may malloc memory */avl_insert( root, data, fcmp, fdup )Avlnode **root;caddr_t data;IFP fcmp;IFP fdup;{ int taller; return( ravl_insert( root, data, &taller, fcmp, fdup, 0 ) );}/* called from delete when root's right subtree has been shortened */static right_balance( root )Avlnode **root;{ int shorter; Avlnode *r, *l; switch( (*root)->avl_bf ) { case RH: /* was right high - equal now */ (*root)->avl_bf = EH; shorter = 1; break; case EH: /* was equal - left high now */ (*root)->avl_bf = LH; shorter = 0; break; case LH: /* was right high - balance */ l = (*root)->avl_left; switch ( l->avl_bf ) { case RH : /* double rotation left */ r = l->avl_right; switch ( r->avl_bf ) { case RH : (*root)->avl_bf = EH; l->avl_bf = LH; break; case EH : (*root)->avl_bf = EH; l->avl_bf = EH; break; case LH : (*root)->avl_bf = RH; l->avl_bf = EH; break; } r->avl_bf = EH; ROTATELEFT( (&l) ) (*root)->avl_left = l; ROTATERIGHT( root ) shorter = 1; break; case EH : /* right rotation */ (*root)->avl_bf = LH; l->avl_bf = RH; ROTATERIGHT( root ); shorter = 0; break; case LH : /* single rotation right */ (*root)->avl_bf = EH; l->avl_bf = EH; ROTATERIGHT( root ) shorter = 1; break; } break; } return( shorter );}/* called from delete when root's left subtree has gotten shorter */static left_balance( root )Avlnode **root;{ int shorter; Avlnode *r, *l; switch( (*root)->avl_bf ) { case LH: /* was left high - equal now */ (*root)->avl_bf = EH; shorter = 1; break; case EH: /* was equal - right high now */ (*root)->avl_bf = RH; shorter = 0; break; case RH: /* was right high - balance */ r = (*root)->avl_right; switch ( r->avl_bf ) { case LH : /* double rotation left */ l = r->avl_left; switch ( l->avl_bf ) { case LH : (*root)->avl_bf = EH; r->avl_bf = RH; break; case EH : (*root)->avl_bf = EH; r->avl_bf = EH; break; case RH : (*root)->avl_bf = LH; r->avl_bf = EH; break; } l->avl_bf = EH; ROTATERIGHT( (&r) ) (*root)->avl_right = r; ROTATELEFT( root ) shorter = 1; break; case EH : /* single rotation left */ (*root)->avl_bf = RH; r->avl_bf = LH; ROTATELEFT( root ); shorter = 0; break; case RH : /* single rotation left */ (*root)->avl_bf = EH; r->avl_bf = EH; ROTATELEFT( root ) shorter = 1; break; } break; } return( shorter );}static caddr_t ravl_delete( root, data, fcmp, shorter )Avlnode **root;caddr_t data;IFP fcmp;int *shorter;{ int shortersubtree = 0; int cmp; caddr_t savedata; Avlnode *minnode, *savenode; if ( *root == NULLAVL ) return( 0 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?