59 |
splay_tree sp; |
splay_tree sp; |
60 |
splay_tree_node node; |
splay_tree_node node; |
61 |
{ |
{ |
62 |
|
splay_tree_node pending = 0; |
63 |
|
splay_tree_node active = 0; |
64 |
|
|
65 |
if (!node) |
if (!node) |
66 |
return; |
return; |
67 |
|
|
68 |
splay_tree_delete_helper (sp, node->left); |
#define KDEL(x) if (sp->delete_key) (*sp->delete_key)(x); |
69 |
splay_tree_delete_helper (sp, node->right); |
#define VDEL(x) if (sp->delete_value) (*sp->delete_value)(x); |
70 |
|
|
71 |
|
KDEL (node->key); |
72 |
|
VDEL (node->value); |
73 |
|
|
74 |
|
/* We use the "key" field to hold the "next" pointer. */ |
75 |
|
node->key = (splay_tree_key)pending; |
76 |
|
pending = (splay_tree_node)node; |
77 |
|
|
78 |
|
/* Now, keep processing the pending list until there aren't any |
79 |
|
more. This is a little more complicated than just recursing, but |
80 |
|
it doesn't toast the stack for large trees. */ |
81 |
|
|
82 |
|
while (pending) |
83 |
|
{ |
84 |
|
active = pending; |
85 |
|
pending = 0; |
86 |
|
while (active) |
87 |
|
{ |
88 |
|
splay_tree_node temp; |
89 |
|
|
90 |
|
/* active points to a node which has its key and value |
91 |
|
deallocated, we just need to process left and right. */ |
92 |
|
|
93 |
if (sp->delete_key) |
if (active->left) |
94 |
(*sp->delete_key)(node->key); |
{ |
95 |
if (sp->delete_value) |
KDEL (active->left->key); |
96 |
(*sp->delete_value)(node->value); |
VDEL (active->left->value); |
97 |
|
active->left->key = (splay_tree_key)pending; |
98 |
|
pending = (splay_tree_node)(active->left); |
99 |
|
} |
100 |
|
if (active->right) |
101 |
|
{ |
102 |
|
KDEL (active->right->key); |
103 |
|
VDEL (active->right->value); |
104 |
|
active->right->key = (splay_tree_key)pending; |
105 |
|
pending = (splay_tree_node)(active->right); |
106 |
|
} |
107 |
|
|
108 |
(*sp->deallocate) ((char*) node, sp->allocate_data); |
temp = active; |
109 |
|
active = (splay_tree_node)(temp->key); |
110 |
|
(*sp->deallocate) ((char*) temp, sp->allocate_data); |
111 |
|
} |
112 |
|
} |
113 |
|
#undef KDEL |
114 |
|
#undef VDEL |
115 |
} |
} |
116 |
|
|
117 |
/* Help splay SP around KEY. PARENT and GRANDPARENT are the parent |
/* Help splay SP around KEY. PARENT and GRANDPARENT are the parent |
275 |
int size; |
int size; |
276 |
void *data ATTRIBUTE_UNUSED; |
void *data ATTRIBUTE_UNUSED; |
277 |
{ |
{ |
278 |
return xmalloc (size); |
return (void *) xmalloc (size); |
279 |
} |
} |
280 |
|
|
281 |
static void |
static void |
513 |
if (comparison < 0) |
if (comparison < 0) |
514 |
return sp->root; |
return sp->root; |
515 |
|
|
516 |
/* Otherwise, find the leftmost element of the right subtree. */ |
/* Otherwise, find the rightmost element of the left subtree. */ |
517 |
node = sp->root->left; |
node = sp->root->left; |
518 |
if (node) |
if (node) |
519 |
while (node->right) |
while (node->right) |
523 |
} |
} |
524 |
|
|
525 |
/* Return the immediate successor KEY, or NULL if there is no |
/* Return the immediate successor KEY, or NULL if there is no |
526 |
predecessor. KEY need not be present in the tree. */ |
successor. KEY need not be present in the tree. */ |
527 |
|
|
528 |
splay_tree_node |
splay_tree_node |
529 |
splay_tree_successor (sp, key) |
splay_tree_successor (sp, key) |
533 |
int comparison; |
int comparison; |
534 |
splay_tree_node node; |
splay_tree_node node; |
535 |
|
|
536 |
/* If the tree is empty, there is certainly no predecessor. */ |
/* If the tree is empty, there is certainly no successor. */ |
537 |
if (!sp->root) |
if (!sp->root) |
538 |
return NULL; |
return NULL; |
539 |
|
|
546 |
if (comparison > 0) |
if (comparison > 0) |
547 |
return sp->root; |
return sp->root; |
548 |
|
|
549 |
/* Otherwise, find the rightmost element of the left subtree. */ |
/* Otherwise, find the leftmost element of the right subtree. */ |
550 |
node = sp->root->right; |
node = sp->root->right; |
551 |
if (node) |
if (node) |
552 |
while (node->left) |
while (node->left) |