7 typedef struct W_Node
{
17 typedef struct W_Bag
{
20 W_Node
*nil
; /* sentinel */
24 void (*destructor
) (void *item
);
27 #define IS_LEFT(node) (node == node->parent->left)
28 #define IS_RIGHT(node) (node == node->parent->right)
30 static void leftRotate(W_Bag
* tree
, W_Node
* node
)
35 node
->right
= node2
->left
;
37 node2
->left
->parent
= node
;
39 node2
->parent
= node
->parent
;
41 if (node
->parent
== tree
->nil
) {
45 node
->parent
->left
= node2
;
47 node
->parent
->right
= node2
;
54 static void rightRotate(W_Bag
* tree
, W_Node
* node
)
59 node
->left
= node2
->right
;
61 node2
->right
->parent
= node
;
63 node2
->parent
= node
->parent
;
65 if (node
->parent
== tree
->nil
) {
69 node
->parent
->left
= node2
;
71 node
->parent
->right
= node2
;
78 static void treeInsert(W_Bag
* tree
, W_Node
* node
)
80 W_Node
*y
= tree
->nil
;
81 W_Node
*x
= tree
->root
;
83 while (x
!= tree
->nil
) {
85 if (node
->index
<= x
->index
)
93 else if (node
->index
<= y
->index
)
99 static void rbTreeInsert(W_Bag
* tree
, W_Node
* node
)
103 treeInsert(tree
, node
);
107 while (node
!= tree
->root
&& node
->parent
->color
== 'R') {
108 if (IS_LEFT(node
->parent
)) {
109 y
= node
->parent
->parent
->right
;
111 if (y
->color
== 'R') {
113 node
->parent
->color
= 'B';
115 node
->parent
->parent
->color
= 'R';
116 node
= node
->parent
->parent
;
119 if (IS_RIGHT(node
)) {
121 leftRotate(tree
, node
);
123 node
->parent
->color
= 'B';
124 node
->parent
->parent
->color
= 'R';
125 rightRotate(tree
, node
->parent
->parent
);
128 y
= node
->parent
->parent
->left
;
130 if (y
->color
== 'R') {
132 node
->parent
->color
= 'B';
134 node
->parent
->parent
->color
= 'R';
135 node
= node
->parent
->parent
;
140 rightRotate(tree
, node
);
142 node
->parent
->color
= 'B';
143 node
->parent
->parent
->color
= 'R';
144 leftRotate(tree
, node
->parent
->parent
);
148 tree
->root
->color
= 'B';
151 static void rbDeleteFixup(W_Bag
* tree
, W_Node
* node
)
155 while (node
!= tree
->root
&& node
->color
== 'B') {
157 w
= node
->parent
->right
;
158 if (w
->color
== 'R') {
160 node
->parent
->color
= 'R';
161 leftRotate(tree
, node
->parent
);
162 w
= node
->parent
->right
;
164 if (w
->left
->color
== 'B' && w
->right
->color
== 'B') {
168 if (w
->right
->color
== 'B') {
169 w
->left
->color
= 'B';
171 rightRotate(tree
, w
);
172 w
= node
->parent
->right
;
174 w
->color
= node
->parent
->color
;
175 node
->parent
->color
= 'B';
176 w
->right
->color
= 'B';
177 leftRotate(tree
, node
->parent
);
181 w
= node
->parent
->left
;
182 if (w
->color
== 'R') {
184 node
->parent
->color
= 'R';
185 rightRotate(tree
, node
->parent
);
186 w
= node
->parent
->left
;
188 if (w
->left
->color
== 'B' && w
->right
->color
== 'B') {
192 if (w
->left
->color
== 'B') {
193 w
->right
->color
= 'B';
196 w
= node
->parent
->left
;
198 w
->color
= node
->parent
->color
;
199 node
->parent
->color
= 'B';
200 w
->left
->color
= 'B';
201 rightRotate(tree
, node
->parent
);
210 static W_Node
*treeMinimum(W_Node
* node
, W_Node
* nil
)
212 while (node
->left
!= nil
)
217 static W_Node
*treeMaximum(W_Node
* node
, W_Node
* nil
)
219 while (node
->right
!= nil
)
224 static W_Node
*treeSuccessor(W_Node
* node
, W_Node
* nil
)
228 if (node
->right
!= nil
) {
229 return treeMinimum(node
->right
, nil
);
232 while (y
!= nil
&& node
== y
->right
) {
239 static W_Node
*treePredecessor(W_Node
* node
, W_Node
* nil
)
243 if (node
->left
!= nil
) {
244 return treeMaximum(node
->left
, nil
);
247 while (y
!= nil
&& node
== y
->left
) {
254 static W_Node
*rbTreeDelete(W_Bag
* tree
, W_Node
* node
)
256 W_Node
*nil
= tree
->nil
;
259 if (node
->left
== nil
|| node
->right
== nil
) {
262 y
= treeSuccessor(node
, nil
);
265 if (y
->left
!= nil
) {
271 x
->parent
= y
->parent
;
273 if (y
->parent
== nil
) {
279 y
->parent
->right
= x
;
283 node
->index
= y
->index
;
284 node
->data
= y
->data
;
286 if (y
->color
== 'B') {
287 rbDeleteFixup(tree
, x
);
293 static W_Node
*treeSearch(W_Node
* root
, W_Node
* nil
, int index
)
295 if (root
== nil
|| root
->index
== index
) {
299 if (index
< root
->index
) {
300 return treeSearch(root
->left
, nil
, index
);
302 return treeSearch(root
->right
, nil
, index
);
306 static W_Node
*treeFind(W_Node
* root
, W_Node
* nil
, void *data
)
310 if (root
== nil
|| root
->data
== data
)
313 tmp
= treeFind(root
->left
, nil
, data
);
317 tmp
= treeFind(root
->right
, nil
, data
);
323 static char buf
[512];
325 static void printNodes(W_Node
* node
, W_Node
* nil
, int depth
)
331 printNodes(node
->left
, nil
, depth
+ 1);
333 memset(buf
, ' ', depth
* 2);
336 printf("%s/(%2i\n", buf
, node
->index
);
338 printf("%s\\(%2i\n", buf
, node
->index
);
340 printNodes(node
->right
, nil
, depth
+ 1);
343 void PrintTree(WMBag
* bag
)
345 W_TreeBag
*tree
= (W_TreeBag
*) bag
->data
;
347 printNodes(tree
->root
, tree
->nil
, 0);
351 WMBag
*WMCreateTreeBag(void)
353 return WMCreateTreeBagWithDestructor(NULL
);
356 WMBag
*WMCreateTreeBagWithDestructor(WMFreeDataProc
* destructor
)
360 bag
= wmalloc(sizeof(WMBag
));
361 bag
->nil
= wmalloc(sizeof(W_Node
));
362 bag
->nil
->left
= bag
->nil
->right
= bag
->nil
->parent
= bag
->nil
;
363 bag
->nil
->index
= WBNotFound
;
364 bag
->root
= bag
->nil
;
365 bag
->destructor
= destructor
;
370 int WMGetBagItemCount(WMBag
* self
)
375 void WMAppendBag(WMBag
* self
, WMBag
* bag
)
380 for (data
= WMBagFirst(bag
, &ptr
); data
!= NULL
; data
= WMBagNext(bag
, &ptr
)) {
381 WMPutInBag(self
, data
);
385 void WMPutInBag(WMBag
* self
, void *item
)
389 ptr
= wmalloc(sizeof(W_Node
));
392 ptr
->index
= self
->count
;
393 ptr
->left
= self
->nil
;
394 ptr
->right
= self
->nil
;
395 ptr
->parent
= self
->nil
;
397 rbTreeInsert(self
, ptr
);
402 void WMInsertInBag(WMBag
* self
, int index
, void *item
)
406 ptr
= wmalloc(sizeof(W_Node
));
410 ptr
->left
= self
->nil
;
411 ptr
->right
= self
->nil
;
412 ptr
->parent
= self
->nil
;
414 rbTreeInsert(self
, ptr
);
416 while ((ptr
= treeSuccessor(ptr
, self
->nil
)) != self
->nil
) {
423 int WMRemoveFromBag(WMBag
* self
, void *item
)
425 W_Node
*ptr
= treeFind(self
->root
, self
->nil
, item
);
427 if (ptr
!= self
->nil
) {
432 tmp
= treeSuccessor(ptr
, self
->nil
);
433 while (tmp
!= self
->nil
) {
435 tmp
= treeSuccessor(tmp
, self
->nil
);
438 ptr
= rbTreeDelete(self
, ptr
);
439 if (self
->destructor
)
440 self
->destructor(ptr
->data
);
449 int WMEraseFromBag(WMBag
* self
, int index
)
451 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
453 if (ptr
!= self
->nil
) {
457 ptr
= rbTreeDelete(self
, ptr
);
458 if (self
->destructor
)
459 self
->destructor(ptr
->data
);
462 wassertrv(self
->count
== 0 || self
->root
->index
>= 0, 1);
470 int WMDeleteFromBag(WMBag
* self
, int index
)
472 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
474 if (ptr
!= self
->nil
) {
479 tmp
= treeSuccessor(ptr
, self
->nil
);
480 while (tmp
!= self
->nil
) {
482 tmp
= treeSuccessor(tmp
, self
->nil
);
485 ptr
= rbTreeDelete(self
, ptr
);
486 if (self
->destructor
)
487 self
->destructor(ptr
->data
);
490 wassertrv(self
->count
== 0 || self
->root
->index
>= 0, 1);
498 void *WMGetFromBag(WMBag
* self
, int index
)
502 node
= treeSearch(self
->root
, self
->nil
, index
);
503 if (node
!= self
->nil
)
509 int WMGetFirstInBag(WMBag
* self
, void *item
)
513 node
= treeFind(self
->root
, self
->nil
, item
);
514 if (node
!= self
->nil
)
520 static int treeCount(W_Node
* root
, W_Node
* nil
, void *item
)
527 if (root
->data
== item
)
530 if (root
->left
!= nil
)
531 count
+= treeCount(root
->left
, nil
, item
);
533 if (root
->right
!= nil
)
534 count
+= treeCount(root
->right
, nil
, item
);
539 int WMCountInBag(WMBag
* self
, void *item
)
541 return treeCount(self
->root
, self
->nil
, item
);
544 void *WMReplaceInBag(WMBag
* self
, int index
, void *item
)
546 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
551 ptr
= rbTreeDelete(self
, ptr
);
552 if (self
->destructor
)
553 self
->destructor(ptr
->data
);
555 } else if (ptr
!= self
->nil
) {
561 ptr
= wmalloc(sizeof(W_Node
));
565 ptr
->left
= self
->nil
;
566 ptr
->right
= self
->nil
;
567 ptr
->parent
= self
->nil
;
569 rbTreeInsert(self
, ptr
);
577 void WMSortBag(WMBag
* self
, WMCompareDataProc
* comparer
)
583 if (self
->count
== 0)
586 items
= wmalloc(sizeof(void *) * self
->count
);
589 tmp
= treeMinimum(self
->root
, self
->nil
);
590 while (tmp
!= self
->nil
) {
591 items
[i
++] = tmp
->data
;
592 tmp
= treeSuccessor(tmp
, self
->nil
);
595 qsort(&items
[0], self
->count
, sizeof(void *), comparer
);
598 tmp
= treeMinimum(self
->root
, self
->nil
);
599 while (tmp
!= self
->nil
) {
601 tmp
->data
= items
[i
++];
602 tmp
= treeSuccessor(tmp
, self
->nil
);
608 static void deleteTree(WMBag
* self
, W_Node
* node
)
610 if (node
== self
->nil
)
613 deleteTree(self
, node
->left
);
615 if (self
->destructor
)
616 self
->destructor(node
->data
);
618 deleteTree(self
, node
->right
);
623 void WMEmptyBag(WMBag
* self
)
625 deleteTree(self
, self
->root
);
626 self
->root
= self
->nil
;
630 void WMFreeBag(WMBag
* self
)
637 static void mapTree(W_Bag
* tree
, W_Node
* node
, void (*function
) (void *, void *), void *data
)
639 if (node
== tree
->nil
)
642 mapTree(tree
, node
->left
, function
, data
);
644 (*function
) (node
->data
, data
);
646 mapTree(tree
, node
->right
, function
, data
);
649 void WMMapBag(WMBag
* self
, void (*function
) (void *, void *), void *data
)
651 mapTree(self
, self
->root
, function
, data
);
654 static int findInTree(W_Bag
* tree
, W_Node
* node
, WMMatchDataProc
* function
, void *cdata
)
658 if (node
== tree
->nil
)
661 index
= findInTree(tree
, node
->left
, function
, cdata
);
662 if (index
!= WBNotFound
)
665 if ((*function
) (node
->data
, cdata
)) {
669 return findInTree(tree
, node
->right
, function
, cdata
);
672 int WMFindInBag(WMBag
* self
, WMMatchDataProc
* match
, void *cdata
)
674 return findInTree(self
, self
->root
, match
, cdata
);
677 void *WMBagFirst(WMBag
* self
, WMBagIterator
* ptr
)
681 node
= treeMinimum(self
->root
, self
->nil
);
683 if (node
== self
->nil
) {
692 void *WMBagLast(WMBag
* self
, WMBagIterator
* ptr
)
697 node
= treeMaximum(self
->root
, self
->nil
);
699 if (node
== self
->nil
) {
708 void *WMBagNext(WMBag
* self
, WMBagIterator
* ptr
)
715 node
= treeSuccessor(*ptr
, self
->nil
);
717 if (node
== self
->nil
) {
726 void *WMBagPrevious(WMBag
* self
, WMBagIterator
* ptr
)
733 node
= treePredecessor(*ptr
, self
->nil
);
735 if (node
== self
->nil
) {
744 void *WMBagIteratorAtIndex(WMBag
* self
, int index
, WMBagIterator
* ptr
)
748 node
= treeSearch(self
->root
, self
->nil
, index
);
750 if (node
== self
->nil
) {
759 int WMBagIndexForIterator(WMBag
* bag
, WMBagIterator ptr
)
761 return ((W_Node
*) ptr
)->index
;