|
|
1.1 root 1: /*************************************************************/
2: /** **/
3: /** Microsoft RPC Examples **/
4: /** Dictionary Application **/
5: /** Copyright(c) Microsoft Corp. 1991 **/
6: /** **/
7: /*************************************************************/
8:
9: #include <stdio.h>
10: #include <malloc.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <ctype.h>
14: #include <windows.h>
15:
16: #include <rpc.h>
17: #include "dict0.h"
18:
19: /************************************************************************/
20: TreeNode Dumbo;
21: // volatile
22: TreeNode *Dummy = &Dumbo; // a global dummy node
23:
24: #define ROTATELEFT tmp=t->right; t->right=tmp->left; tmp->left=t; t=tmp
25: #define ROTATERIGHT tmp=t->left; t->left=tmp->right; tmp->right=t; t=tmp
26: #define LINKLEFT tmp=t; t=t->right; l=l->right=tmp
27: #define LINKRIGHT tmp=t; t=t->left; r=r->left=tmp
28: #define ASSEMBLE r->left=t->right; l->right=t->left; \
29: t->left=Dummy->right; t->right=Dummy->left
30: /************************************************************************/
31:
32: /************************************************************************
33: Basic structure declarations from dict0.h:
34:
35: typedef struct tnode {
36: struct tnode *left; // left child pointer
37: struct tnode *right; // right child pointer
38: void *item; // pointer to some structure
39: } TreeNode;
40:
41: typedef struct dictnode {
42: TreeNode *root; // pointer to the root of a SAT
43: long size; // number of records in dictionary
44: void * state; // reserved for state info
45: // int (*cmp_rec)(void *, void *); comparison function pointer
46: cmp_rec_func cmp_rec;
47: TreeNode* (*splay)(TreeNode *, void *, cmp_rec_func);
48: // pointer to a splay function
49: void (*print_rec)(void *); // one line print function
50: } Dictionary;
51:
52: #define DICT_CURR_ITEM(pDict) pDict->root->item
53:
54: typedef enum {
55: SUCCESS,
56: ITEM_ALREADY_PRESENT,
57: ITEM_NOT_FOUND,
58: FIRST_ITEM,
59: LAST_ITEM,
60: EMPTY_DICTIONARY,
61: NULL_ITEM
62: }
63: Dict_Status;
64: **************************************************************************/
65:
66:
67: /*************************************************************************/
68: /*** MIDL_user_allocate / MIDL_user_free ***/
69: /*************************************************************************/
70:
71: void *
72: MIDL_user_allocate(unsigned long count);
73:
74: void
75: MIDL_user_free(void * p);
76:
77: /*************************************************************************/
78: /*** Minimal Dictionary Operations: ***/
79: /*** ***/
80: /*** Dictionary *Dict_New(Cmp_rec*, Splay*, print_rec*) ***/
81: /*** ***/
82: /*** Dict_Status Dict_Find(Dictionary*, Item*) ***/
83: /*** Dict_Status Dict_Next(Dictionary*, Item*) ***/
84: /*** Dict_Status Dict_Prev(Dictionary*, Item*) ***/
85: /*** Dict_Status Dict_Insert(Dictionary*, Item*) ***/
86: /*** Dict_Status Dict_Delete(Dictionary*, Item**) ***/
87: /*** ***/
88: /*** Item* DICT_CURR_ITEM(Dict*) ***/
89: /*************************************************************************/
90:
91: #define TreeNode_New(pnode, pitem) pnode = \
92: (TreeNode*) MIDL_user_allocate (sizeof(TreeNode)); \
93: pnode->left = pnode->right = NULL; pnode->item = pitem;
94:
95: Dictionary*
96: Dict_New( // returns a new dictionary node
97: int (*cmp_rec) // pointer to item comparison function
98: (void *, void *),
99: TreeNode* (*splay) // pointer to a splay function
100: (TreeNode *, void *, cmp_rec_func),
101: void (*print_rec) // pointer to one line item print routine
102: (void *) )
103: {
104: Dictionary* dp;
105: dp = (Dictionary*)MIDL_user_allocate(sizeof(Dictionary));
106: dp->root = NULL;
107: dp->size = 0;
108: dp->state = NULL;
109: dp->print_rec = print_rec;
110: dp->splay = splay;
111: dp->cmp_rec = cmp_rec;
112: return(dp);
113: }
114:
115:
116: Dict_Status
117: Dict_Find(
118: Dictionary* dp, // Dictionary to be searched.
119: void* item) // Item searched for.
120: {
121: int keycmp;
122: TreeNode* t;
123:
124: if (dp->root == NULL) return (EMPTY_DICTIONARY);
125: if (item == NULL) return(NULL_ITEM);
126: t = dp->root = dp->splay(dp->root, item, dp->cmp_rec);
127: keycmp = (dp->cmp_rec)( t->item, item );
128: if (keycmp != 0)
129: return(ITEM_NOT_FOUND);
130: else return(SUCCESS);
131: }
132:
133: Dict_Status
134: Dict_Next(
135: Dictionary* dp, // Dictionary to be searched.
136: void* item) // A Key item. Advance to successor of item in dp.
137: {
138: TreeNode* t;
139: int keycmp;
140:
141: if (dp->root == NULL) return (EMPTY_DICTIONARY);
142: if (item == NULL) { dp->root = tdSplayLeft(dp->root);
143: return(SUCCESS);
144: }
145: if (item == DICT_CURR_ITEM(dp)) {
146: t = dp->root;
147: keycmp = 0; }
148: else {
149: dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
150: keycmp = (dp->cmp_rec)( item, t->item );
151: }
152: if (keycmp < 0)
153: return(SUCCESS);
154: else if (t->right == NULL) {
155: return(LAST_ITEM); }
156: else {
157: t = dp->root;
158: dp->root = tdSplayLeft(t->right);
159: dp->root->left = t;
160: t->right = NULL;
161: return(SUCCESS);
162: }
163: }
164:
165: Dict_Status
166: Dict_Prev(
167: Dictionary* dp, // Dictionary to be searched.
168: void* item) // A Key item. Retreat to predecessor of item in dp.
169: {
170: TreeNode* t;
171: int keycmp;
172:
173: if (dp->root == NULL) return (EMPTY_DICTIONARY);
174: if (item == NULL) { dp->root = tdSplayRight(dp->root);
175: return(SUCCESS);
176: }
177: if (item == DICT_CURR_ITEM(dp)) {
178: t = dp->root;
179: keycmp = 0; }
180: else {
181: dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
182: keycmp = (dp->cmp_rec)( item, t->item );
183: }
184: if (keycmp > 0)
185: return(SUCCESS);
186: else if (t->left == NULL) {
187: return(FIRST_ITEM); }
188: else {
189: t = dp->root;
190: dp->root = tdSplayRight(t->left);
191: dp->root->right = t;
192: t->left = NULL;
193: return(SUCCESS);
194: }
195: }
196:
197: Dict_Status
198: Dict_Insert( // insert the given item into the tree
199: Dictionary* dp, // the modified dictionary
200: void* item) // the item to be inserted
201: {
202: int keycmp;
203: TreeNode *t, *newNode;
204:
205: if (item == NULL) return(NULL_ITEM);
206: if (dp->root == NULL) {
207: TreeNode_New(newNode, item);
208: dp->root = newNode;
209: dp->size++;
210: return(SUCCESS);
211: }
212: t = dp->root = dp->splay(dp->root, item, dp->cmp_rec);
213: keycmp = (dp->cmp_rec)( t->item, item );
214: if (keycmp == 0)
215: return(ITEM_ALREADY_PRESENT);
216:
217: TreeNode_New(newNode, item);
218: if (keycmp < 0) { // t->item < item
219: newNode->right = t->right;
220: t->right = NULL;
221: newNode->left = t; }
222: else {
223: newNode->left = t->left;
224: t->left = NULL;
225: newNode->right = t;
226: }
227: dp->root = newNode;
228: dp->size++;
229: return(SUCCESS);
230: }
231:
232:
233: Dict_Status
234: Dict_Delete( // delete the given item into from the tree
235: Dictionary* dp, // the modified dictionary
236: void** pItem) // IN: points to the (key) item to be deleted
237: // OUT: points to the item just deleted
238: {
239: TreeNode *t, *r;
240: int keycmp;
241: void* item = *pItem;
242: t = dp->root;
243:
244: if (item == NULL) return(NULL_ITEM);
245: if (dp->root == NULL) return (EMPTY_DICTIONARY);
246: if (item == DICT_CURR_ITEM(dp))
247: keycmp = 0;
248: else {
249: dp->root = t = dp->splay(dp->root, item, dp->cmp_rec);
250: keycmp = (dp->cmp_rec)( item, t->item );
251: }
252: if (keycmp != 0)
253: return(ITEM_NOT_FOUND);
254: *pItem = DICT_CURR_ITEM(dp);
255:
256: if (t->left == NULL) {
257: dp->root = t->right; }
258: else if ( (r = t->right) == NULL) {
259: dp->root = t->left; }
260: else {
261: r = tdSplayLeft(r);
262: // at this point r->left == NULL
263: r->left = t->left;
264: dp->root = r;
265: }
266: t->left = t->right = t->item = NULL;
267: MIDL_user_free(t);
268: dp->size--;
269: return(SUCCESS);
270: }
271:
272:
273: /*************************************************************************/
274: /***** Core functions (internal) *****/
275: /*************************************************************************/
276:
277: TreeNode * // returns the new root
278: tdSplay( // general top down splay
279: TreeNode *root, // the current root of the tree
280: void *keyItem, // pointer to a "key item" searched for
281: int (*cmp)(void *, void *) )
282: // pointer to a comparison function
283: {
284: TreeNode* t=root; // current search point
285: TreeNode* l; // root of "left subtree" < keyItem
286: TreeNode* r; // root of "right subtree" > keyItem
287: int kcmpt, kcmpleft, kcmpright;
288: // cash comparison results
289: TreeNode* tmp;
290:
291: /***/
292: Dummy = &Dumbo;
293: l = Dummy;
294: r = Dummy;
295: /***/
296:
297: if ( (root == NULL) || ((*cmp)(keyItem, root->item) == 0) ) return (root);
298: Dummy->left=Dummy->right=NULL;
299: while ( (kcmpt = (*cmp)(keyItem, t->item)) != 0 ) {
300: if ( kcmpt < 0 ) {
301: if ( t->left == NULL ) break;
302: if ( (kcmpleft = (*cmp)(keyItem, t->left->item)) == 0 ) {
303: LINKRIGHT; }
304: else if ( kcmpleft < 0 ) {
305: ROTATERIGHT;
306: if ( t->left != NULL ) {
307: LINKRIGHT; } }
308: else { // keyItem > t->left->item
309: LINKRIGHT;
310: if ( t->right != NULL ) {
311: LINKLEFT; } } }
312: else { // keyItem > t->item
313: if ( t->right == NULL ) break;
314: if ( (kcmpright = (*cmp)(keyItem, t->right->item)) == 0 ) {
315: LINKLEFT; }
316: else if ( kcmpright > 0 ) {
317: ROTATELEFT;
318: if ( t->right != NULL ) {
319: LINKLEFT; } }
320: else { // keyItem < t->right->item
321: LINKLEFT;
322: if ( t->left != NULL ) {
323: LINKRIGHT; } }
324: }
325: }
326: // assemble:
327: r->left=t->right; l->right=t->left;
328: t->left=Dummy->right; t->right=Dummy->left;
329: return(t);
330: }
331:
332: TreeNode*
333: tdSplayLeft(TreeNode* root)
334: {
335: TreeNode* t=root; // current "search" point
336: TreeNode* l=Dummy; // root of "left subtree" < keyItem
337: TreeNode* r=Dummy; // root of "right subtree" > keyItem
338: TreeNode* tmp;
339:
340: if ((t == NULL) || (t->left == NULL)) return(t);
341: if (t->left->left == NULL) {
342: ROTATERIGHT; return(t); }
343: Dummy->left=Dummy->right=NULL;
344: while ( t->left != NULL ) {
345: ROTATERIGHT;
346: if ( t->left != NULL ) {
347: LINKRIGHT; }
348: }
349: r->left=t->right; l->right=t->left;
350: t->left=Dummy->right; t->right=Dummy->left;
351: return(t);
352: }
353:
354: TreeNode*
355: tdSplayRight(TreeNode* root)
356: {
357: TreeNode* t=root; // current "search" point
358: TreeNode* l=Dummy; // root of "left subtree" < keyItem
359: TreeNode* r=Dummy; // root of "right subtree" > keyItem
360: TreeNode* tmp;
361:
362: if ((t == NULL) || (t->right == NULL)) return(t);
363: Dummy->left=Dummy->right=NULL;
364: while ( t->right != NULL ) {
365: ROTATELEFT;
366: if ( t->right != NULL ) {
367: LINKLEFT; }
368: }
369: r->left=t->right; l->right=t->left;
370: t->left=Dummy->right; t->right=Dummy->left;
371: return(t);
372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.