home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************/
- /** **/
- /** Microsoft RPC Examples **/
- /** Dictionary Application **/
- /** Copyright(c) Microsoft Corp. 1992-1996 **/
- /** **/
- /*************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
-
- #include <rpc.h>
- #include <rpcndr.h>
- #include "dict0.h"
-
- /************************************************************************/
- TreeNode Dumbo;
- // volatile
- TreeNode *Dummy = &Dumbo; // a global dummy node
-
- #define ROTATELEFT tmp=t->right; t->right=tmp->left; tmp->left=t; t=tmp
- #define ROTATERIGHT tmp=t->left; t->left=tmp->right; tmp->right=t; t=tmp
- #define LINKLEFT tmp=t; t=t->right; l=l->right=tmp
- #define LINKRIGHT tmp=t; t=t->left; r=r->left=tmp
- #define ASSEMBLE r->left=t->right; l->right=t->left; \
- t->left=Dummy->right; t->right=Dummy->left
- /************************************************************************/
-
- /************************************************************************
- Basic structure declarations from dict0.h:
-
- typedef struct tnode {
- struct tnode *left; // left child pointer
- struct tnode *right; // right child pointer
- void *item; // pointer to some structure
- } TreeNode;
-
- typedef struct dictnode {
- TreeNode *root; // pointer to the root of a SAT
- long size; // number of records in dictionary
- void * state; // reserved for state info
- cmp_rec_func cmp_rec; // pointer to a comparison function
- TreeNode* (*splay)(TreeNode *, void *, cmp_rec_func);
- // pointer to a splay function
- void (*print_rec)(void *); // one line print function
- } Dictionary;
-
- #define DICT_CURR_ITEM(pDict) pDict->root->item
-
- typedef enum {
- SUCCESS,
- ITEM_ALREADY_PRESENT,
- ITEM_NOT_FOUND,
- FIRST_ITEM,
- LAST_ITEM,
- EMPTY_DICTIONARY,
- NULL_ITEM
- } Dict_Status;
- **************************************************************************/
-
-
- /*************************************************************************/
- /*** Minimal Dictionary Operations: ***/
- /*** ***/
- /*** Dictionary *Dict_New(Cmp_rec*, Splay*, print_rec*) ***/
- /*** ***/
- /*** Dict_Status Dict_Find(Dictionary*, Item*) ***/
- /*** Dict_Status Dict_Next(Dictionary*, Item*) ***/
- /*** Dict_Status Dict_Prev(Dictionary*, Item*) ***/
- /*** Dict_Status Dict_Insert(Dictionary*, Item*) ***/
- /*** Dict_Status Dict_Delete(Dictionary*, Item**) ***/
- /*** ***/
- /*** Item* DICT_CURR_ITEM(Dict*) ***/
- /*************************************************************************/
-
- #define TreeNode_New(pnode, pitem) pnode = \
- (TreeNode*) MIDL_user_allocate (sizeof(TreeNode)); \
- pnode->left = pnode->right = NULL; pnode->item = pitem;
-
- Dictionary*
- Dict_New( // returns a new dictionary node
- int (*cmp_rec) // pointer to item comparison function
- (void *, void *),
- TreeNode* (*splay) // pointer to a splay function
- (TreeNode *, void *, cmp_rec_func),
- void (*print_rec) // pointer to one line item print routine
- (void *) )
- {
- Dictionary* dp;
-
- dp = (Dictionary*) MIDL_user_allocate(sizeof(Dictionary));
- dp->root = NULL;
- dp->size = 0;
- dp->state = NULL;
- dp->print_rec = print_rec;
- dp->splay = splay;
- dp->cmp_rec = cmp_rec;
- return(dp);
- }
-
- Dict_Status
- Dict_Find(
- Dictionary* dp, // Dictionary to be searched.
- void* item) // Item searched for.
- {
- int keycmp;
- TreeNode* t;
-
- if (dp->root == NULL)
- return (EMPTY_DICTIONARY);
- if (item == NULL)
- return(NULL_ITEM);
- t = dp->root = dp->splay(dp->root, item, dp->cmp_rec);
- keycmp = (dp->cmp_rec)( t->item, item );
- if (keycmp != 0)
- return(ITEM_NOT_FOUND);
- else return(SUCCESS);
- }
-
- Dict_Status
- Dict_Next(
- Dictionary* dp, // Dictionary to be searched.
- void* item) // A Key item. Advance to successor of item in dp.
- {
- TreeNode* t;
- int keycmp;
-
- if (dp->root == NULL)
- return (EMPTY_DICTIONARY);
- if (item == NULL) {
- dp->root = tdSplayLeft(dp->root);
- return(SUCCESS);
- }
- if (item == DICT_CURR_ITEM(dp)) {
- t = dp->root;
- keycmp = 0;
- }
- else {
- dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
- keycmp = (dp->cmp_rec) (item, t->item);
- }
- if (keycmp < 0)
- return(SUCCESS);
- else if (t->right == NULL) {
- return(LAST_ITEM);
- }
- else {
- t = dp->root;
- dp->root = tdSplayLeft(t->right);
- dp->root->left = t;
- t->right = NULL;
- return(SUCCESS);
- }
- }
-
- Dict_Status
- Dict_Prev(
- Dictionary* dp, // Dictionary to be searched.
- void* item) // A Key item. Retreat to predecessor of item in dp.
- {
- TreeNode* t;
- int keycmp;
-
- if (dp->root == NULL)
- return (EMPTY_DICTIONARY);
- if (item == NULL) {
- dp->root = tdSplayRight(dp->root);
- return(SUCCESS);
- }
- if (item == DICT_CURR_ITEM(dp)) {
- t = dp->root;
- keycmp = 0;
- }
- else {
- dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
- keycmp = (dp->cmp_rec) (item, t->item);
- }
- if (keycmp > 0)
- return(SUCCESS);
- else if (t->left == NULL) {
- return(FIRST_ITEM);
- }
- else {
- t = dp->root;
- dp->root = tdSplayRight(t->left);
- dp->root->right = t;
- t->left = NULL;
- return(SUCCESS);
- }
- }
-
- Dict_Status
- Dict_Insert( // insert the given item into the tree
- Dictionary* dp, // the modified dictionary
- void* item) // the item to be inserted
- {
- int keycmp;
- TreeNode *t, *newNode;
-
- if (item == NULL)
- return(NULL_ITEM);
- if (dp->root == NULL) {
- TreeNode_New(newNode, item);
- dp->root = newNode;
- dp->size++;
- return(SUCCESS);
- }
- t = dp->root = dp->splay(dp->root, item, dp->cmp_rec);
- keycmp = (dp->cmp_rec)( t->item, item );
- if (keycmp == 0)
- return(ITEM_ALREADY_PRESENT);
-
- TreeNode_New(newNode, item);
- if (keycmp < 0) { // t->item < item
- newNode->right = t->right;
- t->right = NULL;
- newNode->left = t;
- }
- else {
- newNode->left = t->left;
- t->left = NULL;
- newNode->right = t;
- }
- dp->root = newNode;
- dp->size++;
- return(SUCCESS);
- }
-
-
- Dict_Status
- Dict_Delete( // delete the given item into from the tree
- Dictionary* dp, // the modified dictionary
- void** pItem) // IN: points to the (key) item to be deleted
- // OUT: points to the item just deleted
- {
- TreeNode *t, *r;
- int keycmp;
- void* item = *pItem;
- t = dp->root;
-
- if (item == NULL)
- return(NULL_ITEM);
- if (dp->root == NULL)
- return (EMPTY_DICTIONARY);
- if (item == DICT_CURR_ITEM(dp))
- keycmp = 0;
- else {
- dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
- keycmp = (dp->cmp_rec)( item, t->item );
- }
- if (keycmp != 0)
- return(ITEM_NOT_FOUND);
- *pItem = DICT_CURR_ITEM(dp);
-
- if (t->left == NULL) {
- dp->root = t->right;
- }
- else if ((r = t->right) == NULL) {
- dp->root = t->left;
- }
- else {
- r = tdSplayLeft(r);
- // at this point r->left == NULL
- r->left = t->left;
- dp->root = r;
- }
- t->left = t->right = t->item = NULL;
- MIDL_user_free(t);
- dp->size--;
- return(SUCCESS);
- }
-
-
- /*************************************************************************/
- /***** Core functions (internal) *****/
- /*************************************************************************/
-
- TreeNode * // returns the new root
- tdSplay( // general top down splay
- TreeNode *root, // the current root of the tree
- void *keyItem, // pointer to a "key item" searched for
- int (*cmp)(void *, void *) )
- // pointer to a comparison function
- {
- TreeNode* t=root; // current search point
- TreeNode* l; // root of "left subtree" < keyItem
- TreeNode* r; // root of "right subtree" > keyItem
- int kcmpt, kcmpleft, kcmpright;
- // cash comparison results
- TreeNode* tmp;
-
- /***/
- Dummy = &Dumbo;
- l = Dummy;
- r = Dummy;
- /***/
-
- if ( (root == NULL) || ((*cmp)(keyItem, root->item) == 0) )
- return(root);
- Dummy->left = Dummy->right = NULL;
- while ( (kcmpt = (*cmp)(keyItem, t->item)) != 0 ) {
- if ( kcmpt < 0 ) {
- if ( t->left == NULL )
- break;
- if ( (kcmpleft = (*cmp)(keyItem, t->left->item)) == 0 ) {
- LINKRIGHT;
- }
- else if ( kcmpleft < 0 ) {
- ROTATERIGHT;
- if ( t->left != NULL ) {
- LINKRIGHT;
- }
- }
- else { // keyItem > t->left->item
- LINKRIGHT;
- if ( t->right != NULL ) {
- LINKLEFT;
- }
- }
- }
- else { // keyItem > t->item
- if ( t->right == NULL )
- break;
- if ( (kcmpright = (*cmp)(keyItem, t->right->item)) == 0 ) {
- LINKLEFT;
- }
- else if ( kcmpright > 0 ) {
- ROTATELEFT;
- if ( t->right != NULL ) {
- LINKLEFT;
- }
- }
- else { // keyItem < t->right->item
- LINKLEFT;
- if ( t->left != NULL ) {
- LINKRIGHT;
- }
- }
- }
- }
-
- ASSEMBLE;
- return(t);
- }
-
- TreeNode*
- tdSplayLeft(TreeNode* root)
- {
- TreeNode* t=root; // current "search" point
- TreeNode* l=Dummy; // root of "left subtree" < keyItem
- TreeNode* r=Dummy; // root of "right subtree" > keyItem
- TreeNode* tmp;
-
- if ( (t == NULL) || (t->left == NULL) )
- return(t);
- if ( t->left->left == NULL ) {
- ROTATERIGHT;
- return(t);
- }
- Dummy->left = Dummy->right = NULL;
- while ( t->left != NULL ) {
- ROTATERIGHT;
- if ( t->left != NULL ) {
- LINKRIGHT;
- }
- }
-
- ASSEMBLE;
- return(t);
- }
-
- TreeNode*
- tdSplayRight(TreeNode* root)
- {
- TreeNode* t=root; // current "search" point
- TreeNode* l=Dummy; // root of "left subtree" < keyItem
- TreeNode* r=Dummy; // root of "right subtree" > keyItem
- TreeNode* tmp;
-
- if ( (t == NULL) || (t->right == NULL) )
- return(t);
- Dummy->left = Dummy->right = NULL;
- while ( t->right != NULL ) {
- ROTATELEFT;
- if ( t->right != NULL ) {
- LINKLEFT;
- }
- }
-
- ASSEMBLE;
- return(t);
- }
-