📄 ubi_bintree.h
字号:
* * static ubi_trNewTree( MyTree, cmpfn, ubi_trDUPKEY ); * * is equivalent to * * static ubi_trRoot MyTree[1] * = {{ NULL, cmpfn, 0, ubi_trDUPKEY }}; * * -------------------------------------------------------------------------- ** */#define ubi_trCount( R ) (((ubi_trRootPtr)(R))->count)#define ubi_trNewTree( N, C, F ) ubi_trRoot (N)[1] = {{ NULL, (C), 0, (F) }}/* -------------------------------------------------------------------------- ** * Typedefs... * * ubi_trBool - Your typcial true or false... * * Item Pointer: The ubi_btItemPtr is a generic pointer. It is used to * indicate a key that is being searched for within the tree. * Searching occurs whenever the ubi_trFind(), ubi_trLocate(), * or ubi_trInsert() functions are called. * -------------------------------------------------------------------------- ** */typedef unsigned char ubi_trBool;typedef void *ubi_btItemPtr; /* A pointer to key data within a node. *//* ------------------------------------------------------------------------- ** * Binary Tree Node Structure: This structure defines the basic elements of * the tree nodes. In general you *SHOULD NOT PLAY WITH THESE FIELDS*! * But, of course, I have to put the structure into this header so that * you can use it as a building block. * * The fields are as follows: * Link - an array of pointers. These pointers are manipulated by * the BT routines. The pointers indicate the left and right * child nodes and the parent node. By keeping track of the * parent pointer, we avoid the need for recursive routines or * hand-tooled stacks to keep track of our path back to the * root. The use of these pointers is subject to change without * notice. * gender - a one-byte field indicating whether the node is the RIGHT or * LEFT child of its parent. If the node is the root of the * tree, gender will be PARENT. * balance - only used by the AVL tree module. This field indicates * the height balance at a given node. See ubi_AVLtree for * details. * * ------------------------------------------------------------------------- ** */typedef struct ubi_btNodeStruct { struct ubi_btNodeStruct *Link[ 3 ]; char gender; char balance; } ubi_btNode;typedef ubi_btNode *ubi_btNodePtr; /* Pointer to an ubi_btNode structure. *//* ------------------------------------------------------------------------- ** * The next three typedefs define standard function types used by the binary * tree management routines. In particular: * * ubi_btCompFunc is a pointer to a comparison function. Comparison * functions are passed an ubi_btItemPtr and an * ubi_btNodePtr. They return a value that is (<0), 0, * or (>0) to indicate that the Item is (respectively) * "less than", "equal to", or "greater than" the Item * contained within the node. (See ubi_btInitTree()). * ubi_btActionRtn is a pointer to a function that may be called for each * node visited when performing a tree traversal (see * ubi_btTraverse()). The function will be passed two * parameters: the first is a pointer to a node in the * tree, the second is a generic pointer that may point to * anything that you like. * ubi_btKillNodeRtn is a pointer to a function that will deallocate the * memory used by a node (see ubi_btKillTree()). Since * memory management is left up to you, deallocation may * mean anything that you want it to mean. Just remember * that the tree *will* be destroyed and that none of the * node pointers will be valid any more. * ------------------------------------------------------------------------- ** */typedef int (*ubi_btCompFunc)( ubi_btItemPtr, ubi_btNodePtr );typedef void (*ubi_btActionRtn)( ubi_btNodePtr, void * );typedef void (*ubi_btKillNodeRtn)( ubi_btNodePtr );/* -------------------------------------------------------------------------- ** * Tree Root Structure: This structure gives us a convenient handle for * accessing whole binary trees. The fields are: * root - A pointer to the root node of the tree. * count - A count of the number of nodes stored in the tree. * cmp - A pointer to the comparison routine to be used when building or * searching the tree. * flags - A set of bit flags. Two flags are currently defined: * * ubi_trOVERWRITE - If set, this flag indicates that a new node should * (bit 0x01) overwrite an old node if the two have identical * keys (ie., the keys are equal). * ubi_trDUPKEY - If set, this flag indicates that the tree is * (bit 0x02) allowed to contain nodes with duplicate keys. * * NOTE: ubi_trInsert() tests ubi_trDUPKEY before ubi_trOVERWRITE. * * All of these values are set when you initialize the root structure by * calling ubi_trInitTree(). * -------------------------------------------------------------------------- ** */typedef struct { ubi_btNodePtr root; /* A pointer to the root node of the tree */ ubi_btCompFunc cmp; /* A pointer to the tree's comparison function */ unsigned long count; /* A count of the number of nodes in the tree */ char flags; /* Overwrite Y|N, Duplicate keys Y|N... */ } ubi_btRoot;typedef ubi_btRoot *ubi_btRootPtr; /* Pointer to an ubi_btRoot structure. *//* -------------------------------------------------------------------------- ** * Function Prototypes. */long ubi_btSgn( long x ); /* ------------------------------------------------------------------------ ** * Return the sign of x; {negative,zero,positive} ==> {-1, 0, 1}. * * Input: x - a signed long integer value. * * Output: the "sign" of x, represented as follows: * -1 == negative * 0 == zero (no sign) * 1 == positive * * Note: This utility is provided in order to facilitate the conversion * of C comparison function return values into BinTree direction * values: {LEFT, PARENT, EQUAL}. It is INCORPORATED into the * AbNormal() conversion macro! * * ------------------------------------------------------------------------ ** */ubi_btNodePtr ubi_btInitNode( ubi_btNodePtr NodePtr ); /* ------------------------------------------------------------------------ ** * Initialize a tree node. * * Input: a pointer to a ubi_btNode structure to be initialized. * Output: a pointer to the initialized ubi_btNode structure (ie. the * same as the input pointer). * ------------------------------------------------------------------------ ** */ubi_btRootPtr ubi_btInitTree( ubi_btRootPtr RootPtr, ubi_btCompFunc CompFunc, char Flags ); /* ------------------------------------------------------------------------ ** * Initialize the fields of a Tree Root header structure. * * Input: RootPtr - a pointer to an ubi_btRoot structure to be * initialized. * CompFunc - a pointer to a comparison function that will be used * whenever nodes in the tree must be compared against * outside values. * Flags - One bytes worth of flags. Flags include * ubi_trOVERWRITE and ubi_trDUPKEY. See the header * file for more info. * * Output: a pointer to the initialized ubi_btRoot structure (ie. the * same value as RootPtr). * * Note: The interface to this function has changed from that of * previous versions. The <Flags> parameter replaces two * boolean parameters that had the same basic effect. * ------------------------------------------------------------------------ ** */ubi_trBool ubi_btInsert( ubi_btRootPtr RootPtr, ubi_btNodePtr NewNode, ubi_btItemPtr ItemPtr, ubi_btNodePtr *OldNode ); /* ------------------------------------------------------------------------ ** * This function uses a non-recursive algorithm to add a new element to the * tree. * * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates * the root of the tree to which NewNode is to be added. * NewNode - a pointer to an ubi_btNode structure that is NOT * part of any tree. * ItemPtr - A pointer to the sort key that is stored within * *NewNode. ItemPtr MUST point to information stored * in *NewNode or an EXACT DUPLICATE. The key data * indicated by ItemPtr is used to place the new node * into the tree. * OldNode - a pointer to an ubi_btNodePtr. When searching * the tree, a duplicate node may be found. If * duplicates are allowed, then the new node will * be simply placed into the tree. If duplicates * are not allowed, however, then one of two things * may happen. * 1) if overwritting *is not* allowed, this * function will return FALSE (indicating that * the new node could not be inserted), and * *OldNode will point to the duplicate that is * still in the tree. * 2) if overwritting *is* allowed, then this * function will swap **OldNode for *NewNode. * In this case, *OldNode will point to the node * that was removed (thus allowing you to free * the node). * ** If you are using overwrite mode, ALWAYS ** * ** check the return value of this parameter! ** * Note: You may pass NULL in this parameter, the * function knows how to cope. If you do this, * however, there will be no way to return a * pointer to an old (ie. replaced) node (which is * a problem if you are using overwrite mode). * * Output: a boolean value indicating success or failure. The function * will return FALSE if the node could not be added to the tree. * Such failure will only occur if duplicates are not allowed, * nodes cannot be overwritten, AND a duplicate key was found * within the tree. * ------------------------------------------------------------------------ ** */ubi_btNodePtr ubi_btRemove( ubi_btRootPtr RootPtr, ubi_btNodePtr DeadNode ); /* ------------------------------------------------------------------------ ** * This function removes the indicated node from the tree. * * Input: RootPtr - A pointer to the header of the tree that contains * the node to be removed. * DeadNode - A pointer to the node that will be removed. * * Output: This function returns a pointer to the node that was removed * from the tree (ie. the same as DeadNode). * * Note: The node MUST be in the tree indicated by RootPtr. If not, * strange and evil things will happen to your trees. * ------------------------------------------------------------------------ ** */ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr, ubi_btItemPtr FindMe, ubi_trCompOps CompOp ); /* ------------------------------------------------------------------------ ** * The purpose of ubi_btLocate() is to find a node or set of nodes given * a target value and a "comparison operator". The Locate() function is * more flexible and (in the case of trees that may contain dupicate keys) * more precise than the ubi_btFind() function. The latter is faster, * but it only searches for exact matches and, if the tree contains * duplicates, Find() may return a pointer to any one of the duplicate- * keyed records. * * Input: * RootPtr - A pointer to the header of the tree to be searched. * FindMe - An ubi_btItemPtr that indicates the key for which to * search. * CompOp - One of the following: * CompOp Return a pointer to the node with * ------ --------------------------------- * ubi_trLT - the last key value that is less * than FindMe. * ubi_trLE - the first key matching FindMe, or * the last key that is less than * FindMe. * ubi_trEQ - the first key matching FindMe. * ubi_trGE - the first key matching FindMe, or the * first key greater than FindMe. * ubi_trGT - the first key greater than FindMe. * Output: * A pointer to the node matching the criteria listed above under * CompOp, or NULL if no node matched the criteria. * * Notes: * In the case of trees with duplicate keys, Locate() will behave as * follows: * * Find: 3 Find: 3 * Keys: 1 2 2 2 3 3 3 3 3 4 4 Keys: 1 1 2 2 2 4 4 5 5 5 6 * ^ ^ ^ ^ ^ * LT EQ GT LE GE * * That is, when returning a pointer to a node with a key that is LESS * THAN the target key (FindMe), Locate() will return a pointer to the * LAST matching node. * When returning a pointer to a node with a key that is GREATER * THAN the target key (FindMe), Locate() will return a pointer to the * FIRST matching node.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -