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 static int treeDeleteNode(WMBag
* self
, W_Node
*ptr
)
425 if (ptr
!= self
->nil
) {
430 tmp
= treeSuccessor(ptr
, self
->nil
);
431 while (tmp
!= self
->nil
) {
433 tmp
= treeSuccessor(tmp
, self
->nil
);
436 ptr
= rbTreeDelete(self
, ptr
);
437 if (self
->destructor
)
438 self
->destructor(ptr
->data
);
445 int WMRemoveFromBag(WMBag
* self
, void *item
)
447 W_Node
*ptr
= treeFind(self
->root
, self
->nil
, item
);
448 return treeDeleteNode(self
, ptr
);
451 int WMEraseFromBag(WMBag
* self
, int index
)
453 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
455 if (ptr
!= self
->nil
) {
459 ptr
= rbTreeDelete(self
, ptr
);
460 if (self
->destructor
)
461 self
->destructor(ptr
->data
);
464 wassertrv(self
->count
== 0 || self
->root
->index
>= 0, 1);
472 int WMDeleteFromBag(WMBag
* self
, int index
)
474 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
475 return treeDeleteNode(self
, ptr
);
478 void *WMGetFromBag(WMBag
* self
, int index
)
482 node
= treeSearch(self
->root
, self
->nil
, index
);
483 if (node
!= self
->nil
)
489 int WMGetFirstInBag(WMBag
* self
, void *item
)
493 node
= treeFind(self
->root
, self
->nil
, item
);
494 if (node
!= self
->nil
)
500 static int treeCount(W_Node
* root
, W_Node
* nil
, void *item
)
507 if (root
->data
== item
)
510 if (root
->left
!= nil
)
511 count
+= treeCount(root
->left
, nil
, item
);
513 if (root
->right
!= nil
)
514 count
+= treeCount(root
->right
, nil
, item
);
519 int WMCountInBag(WMBag
* self
, void *item
)
521 return treeCount(self
->root
, self
->nil
, item
);
524 void *WMReplaceInBag(WMBag
* self
, int index
, void *item
)
526 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
531 ptr
= rbTreeDelete(self
, ptr
);
532 if (self
->destructor
)
533 self
->destructor(ptr
->data
);
535 } else if (ptr
!= self
->nil
) {
541 ptr
= wmalloc(sizeof(W_Node
));
545 ptr
->left
= self
->nil
;
546 ptr
->right
= self
->nil
;
547 ptr
->parent
= self
->nil
;
549 rbTreeInsert(self
, ptr
);
557 void WMSortBag(WMBag
* self
, WMCompareDataProc
* comparer
)
563 if (self
->count
== 0)
566 items
= wmalloc(sizeof(void *) * self
->count
);
569 tmp
= treeMinimum(self
->root
, self
->nil
);
570 while (tmp
!= self
->nil
) {
571 items
[i
++] = tmp
->data
;
572 tmp
= treeSuccessor(tmp
, self
->nil
);
575 qsort(&items
[0], self
->count
, sizeof(void *), comparer
);
578 tmp
= treeMinimum(self
->root
, self
->nil
);
579 while (tmp
!= self
->nil
) {
581 tmp
->data
= items
[i
++];
582 tmp
= treeSuccessor(tmp
, self
->nil
);
588 static void deleteTree(WMBag
* self
, W_Node
* node
)
590 if (node
== self
->nil
)
593 deleteTree(self
, node
->left
);
595 if (self
->destructor
)
596 self
->destructor(node
->data
);
598 deleteTree(self
, node
->right
);
603 void WMEmptyBag(WMBag
* self
)
605 deleteTree(self
, self
->root
);
606 self
->root
= self
->nil
;
610 void WMFreeBag(WMBag
* self
)
617 static void mapTree(W_Bag
* tree
, W_Node
* node
, void (*function
) (void *, void *), void *data
)
619 if (node
== tree
->nil
)
622 mapTree(tree
, node
->left
, function
, data
);
624 (*function
) (node
->data
, data
);
626 mapTree(tree
, node
->right
, function
, data
);
629 void WMMapBag(WMBag
* self
, void (*function
) (void *, void *), void *data
)
631 mapTree(self
, self
->root
, function
, data
);
634 static int findInTree(W_Bag
* tree
, W_Node
* node
, WMMatchDataProc
* function
, void *cdata
)
638 if (node
== tree
->nil
)
641 index
= findInTree(tree
, node
->left
, function
, cdata
);
642 if (index
!= WBNotFound
)
645 if ((*function
) (node
->data
, cdata
)) {
649 return findInTree(tree
, node
->right
, function
, cdata
);
652 int WMFindInBag(WMBag
* self
, WMMatchDataProc
* match
, void *cdata
)
654 return findInTree(self
, self
->root
, match
, cdata
);
657 void *WMBagFirst(WMBag
* self
, WMBagIterator
* ptr
)
661 node
= treeMinimum(self
->root
, self
->nil
);
663 if (node
== self
->nil
) {
672 void *WMBagLast(WMBag
* self
, WMBagIterator
* ptr
)
677 node
= treeMaximum(self
->root
, self
->nil
);
679 if (node
== self
->nil
) {
688 void *WMBagNext(WMBag
* self
, WMBagIterator
* ptr
)
695 node
= treeSuccessor(*ptr
, self
->nil
);
697 if (node
== self
->nil
) {
706 void *WMBagPrevious(WMBag
* self
, WMBagIterator
* ptr
)
713 node
= treePredecessor(*ptr
, self
->nil
);
715 if (node
== self
->nil
) {
724 void *WMBagIteratorAtIndex(WMBag
* self
, int index
, WMBagIterator
* ptr
)
728 node
= treeSearch(self
->root
, self
->nil
, index
);
730 if (node
== self
->nil
) {
739 int WMBagIndexForIterator(WMBag
* bag
, WMBagIterator ptr
)
741 /* Parameter not used, but tell the compiler that it is ok */
744 return ((W_Node
*) ptr
)->index
;