11 typedef struct W_Node
{
12 struct W_Node
*parent
;
22 typedef struct W_Bag
{
25 W_Node
*nil
; /* sentinel */
29 void (*destructor
)(void *item
);
34 #define IS_LEFT(node) (node == node->parent->left)
35 #define IS_RIGHT(node) (node == node->parent->right)
40 leftRotate(W_Bag
*tree
, W_Node
*node
)
45 node
->right
= node2
->left
;
47 node2
->left
->parent
= node
;
49 node2
->parent
= node
->parent
;
51 if (node
->parent
== tree
->nil
) {
55 node
->parent
->left
= node2
;
57 node
->parent
->right
= node2
;
67 rightRotate(W_Bag
*tree
, W_Node
*node
)
72 node
->left
= node2
->right
;
74 node2
->right
->parent
= node
;
76 node2
->parent
= node
->parent
;
78 if (node
->parent
== tree
->nil
) {
82 node
->parent
->left
= node2
;
84 node
->parent
->right
= node2
;
93 treeInsert(W_Bag
*tree
, W_Node
*node
)
95 W_Node
*y
= tree
->nil
;
96 W_Node
*x
= tree
->root
;
98 while (x
!= tree
->nil
) {
100 if (node
->index
<= x
->index
)
108 else if (node
->index
<= y
->index
)
116 rbTreeInsert(W_Bag
*tree
, W_Node
*node
)
120 treeInsert(tree
, node
);
124 while (node
!= tree
->root
&& node
->parent
->color
== 'R') {
125 if (IS_LEFT(node
->parent
)) {
126 y
= node
->parent
->parent
->right
;
128 if (y
->color
== 'R') {
130 node
->parent
->color
= 'B';
132 node
->parent
->parent
->color
= 'R';
133 node
= node
->parent
->parent
;
136 if (IS_RIGHT(node
)) {
138 leftRotate(tree
, node
);
140 node
->parent
->color
= 'B';
141 node
->parent
->parent
->color
= 'R';
142 rightRotate(tree
, node
->parent
->parent
);
145 y
= node
->parent
->parent
->left
;
147 if (y
->color
== 'R') {
149 node
->parent
->color
= 'B';
151 node
->parent
->parent
->color
= 'R';
152 node
= node
->parent
->parent
;
157 rightRotate(tree
, node
);
159 node
->parent
->color
= 'B';
160 node
->parent
->parent
->color
= 'R';
161 leftRotate(tree
, node
->parent
->parent
);
165 tree
->root
->color
= 'B';
170 rbDeleteFixup(W_Bag
*tree
, W_Node
*node
)
174 while (node
!= tree
->root
&& node
->color
== 'B') {
176 w
= node
->parent
->right
;
177 if (w
->color
== 'R') {
179 node
->parent
->color
= 'R';
180 leftRotate(tree
, node
->parent
);
181 w
= node
->parent
->right
;
183 if (w
->left
->color
== 'B' && w
->right
->color
== 'B') {
187 if (w
->right
->color
== 'B') {
188 w
->left
->color
= 'B';
190 rightRotate(tree
, w
);
191 w
= node
->parent
->right
;
193 w
->color
= node
->parent
->color
;
194 node
->parent
->color
= 'B';
195 w
->right
->color
= 'B';
196 leftRotate(tree
, node
->parent
);
200 w
= node
->parent
->left
;
201 if (w
->color
== 'R') {
203 node
->parent
->color
= 'R';
204 rightRotate(tree
, node
->parent
);
205 w
= node
->parent
->left
;
207 if (w
->left
->color
== 'B' && w
->right
->color
== 'B') {
211 if (w
->left
->color
== 'B') {
212 w
->right
->color
= 'B';
215 w
= node
->parent
->left
;
217 w
->color
= node
->parent
->color
;
218 node
->parent
->color
= 'B';
219 w
->left
->color
= 'B';
220 rightRotate(tree
, node
->parent
);
231 treeMinimum(W_Node
*node
, W_Node
*nil
)
233 while (node
->left
!= nil
)
240 treeMaximum(W_Node
*node
, W_Node
*nil
)
242 while (node
->right
!= nil
)
249 treeSuccessor(W_Node
*node
, W_Node
*nil
)
253 if (node
->right
!= nil
) {
254 return treeMinimum(node
->right
, nil
);
257 while (y
!= nil
&& node
== y
->right
) {
266 treePredecessor(W_Node
*node
, W_Node
*nil
)
270 if (node
->left
!= nil
) {
271 return treeMaximum(node
->left
, nil
);
274 while (y
!= nil
&& node
== y
->left
) {
283 rbTreeDelete(W_Bag
*tree
, W_Node
*node
)
285 W_Node
*nil
= tree
->nil
;
288 if (node
->left
== nil
|| node
->right
== nil
) {
291 y
= treeSuccessor(node
, nil
);
294 if (y
->left
!= nil
) {
300 x
->parent
= y
->parent
;
302 if (y
->parent
== nil
) {
308 y
->parent
->right
= x
;
312 node
->index
= y
->index
;
313 node
->data
= y
->data
;
315 if (y
->color
== 'B') {
316 rbDeleteFixup(tree
, x
);
324 treeSearch(W_Node
*root
, W_Node
*nil
, int index
)
326 if (root
== nil
|| root
->index
== index
) {
330 if (index
< root
->index
) {
331 return treeSearch(root
->left
, nil
, index
);
333 return treeSearch(root
->right
, nil
, index
);
339 treeFind(W_Node
*root
, W_Node
*nil
, void *data
)
343 if (root
== nil
|| root
->data
== data
)
346 tmp
= treeFind(root
->left
, nil
, data
);
350 tmp
= treeFind(root
->right
, nil
, data
);
358 static char buf
[512];
361 printNodes(W_Node
*node
, W_Node
*nil
, int depth
)
367 printNodes(node
->left
, nil
, depth
+1);
369 memset(buf
, ' ', depth
*2);
372 printf("%s/(%2i\n", buf
, node
->index
);
374 printf("%s\\(%2i\n", buf
, node
->index
);
376 printNodes(node
->right
, nil
, depth
+1);
381 PrintTree(WMBag
*bag
)
383 W_TreeBag
*tree
= (W_TreeBag
*)bag
->data
;
385 printNodes(tree
->root
, tree
->nil
, 0);
391 WMCreateTreeBag(void)
393 return WMCreateTreeBagWithDestructor(NULL
);
398 WMCreateTreeBagWithDestructor(WMFreeDataProc
*destructor
)
402 bag
= wmalloc(sizeof(WMBag
));
404 memset(bag
, 0, sizeof(WMBag
));
406 bag
->nil
= wmalloc(sizeof(W_Node
));
407 memset(bag
->nil
, 0, sizeof(W_Node
));
408 bag
->nil
->left
= bag
->nil
->right
= bag
->nil
->parent
= bag
->nil
;
409 bag
->nil
->index
= WBNotFound
;
411 bag
->root
= bag
->nil
;
413 bag
->destructor
= destructor
;
420 WMGetBagItemCount(WMBag
*self
)
427 WMAppendBag(WMBag
*self
, WMBag
*bag
)
432 for (data
= WMBagFirst(bag
, &ptr
); data
!= NULL
; data
= WMBagNext(bag
, &ptr
)) {
433 WMPutInBag(self
, data
);
439 WMPutInBag(WMBag
*self
, void *item
)
443 ptr
= wmalloc(sizeof(W_Node
));
446 ptr
->index
= self
->count
;
447 ptr
->left
= self
->nil
;
448 ptr
->right
= self
->nil
;
449 ptr
->parent
= self
->nil
;
451 rbTreeInsert(self
, ptr
);
458 WMInsertInBag(WMBag
*self
, int index
, void *item
)
462 ptr
= wmalloc(sizeof(W_Node
));
466 ptr
->left
= self
->nil
;
467 ptr
->right
= self
->nil
;
468 ptr
->parent
= self
->nil
;
470 rbTreeInsert(self
, ptr
);
472 while ((ptr
= treeSuccessor(ptr
, self
->nil
)) != self
->nil
) {
482 WMRemoveFromBag(WMBag
*self
, void *item
)
484 W_Node
*ptr
= treeFind(self
->root
, self
->nil
, item
);
486 if (ptr
!= self
->nil
) {
491 tmp
= treeSuccessor(ptr
, self
->nil
);
492 while (tmp
!= self
->nil
) {
494 tmp
= treeSuccessor(tmp
, self
->nil
);
497 ptr
= rbTreeDelete(self
, ptr
);
498 if (self
->destructor
)
499 self
->destructor(ptr
->data
);
510 WMEraseFromBag(WMBag
*self
, int index
)
512 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
514 if (ptr
!= self
->nil
) {
518 ptr
= rbTreeDelete(self
, ptr
);
519 if (self
->destructor
)
520 self
->destructor(ptr
->data
);
523 wassertrv(self
->count
== 0||self
->root
->index
>= 0, 1);
533 WMDeleteFromBag(WMBag
*self
, int index
)
535 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
537 if (ptr
!= self
->nil
) {
542 tmp
= treeSuccessor(ptr
, self
->nil
);
543 while (tmp
!= self
->nil
) {
545 tmp
= treeSuccessor(tmp
, self
->nil
);
548 ptr
= rbTreeDelete(self
, ptr
);
549 if (self
->destructor
)
550 self
->destructor(ptr
->data
);
553 wassertrv(self
->count
== 0||self
->root
->index
>= 0, 1);
563 WMGetFromBag(WMBag
*self
, int index
)
567 node
= treeSearch(self
->root
, self
->nil
, index
);
568 if (node
!= self
->nil
)
576 WMGetFirstInBag(WMBag
*self
, void *item
)
580 node
= treeFind(self
->root
, self
->nil
, item
);
581 if (node
!= self
->nil
)
590 treeCount(W_Node
*root
, W_Node
*nil
, void *item
)
597 if (root
->data
== item
)
600 if (root
->left
!= nil
)
601 count
+= treeCount(root
->left
, nil
, item
);
603 if (root
->right
!= nil
)
604 count
+= treeCount(root
->right
, nil
, item
);
612 WMCountInBag(WMBag
*self
, void *item
)
614 return treeCount(self
->root
, self
->nil
, item
);
619 WMReplaceInBag(WMBag
*self
, int index
, void *item
)
621 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
626 ptr
= rbTreeDelete(self
, ptr
);
627 if (self
->destructor
)
628 self
->destructor(ptr
->data
);
630 } else if (ptr
!= self
->nil
) {
636 ptr
= wmalloc(sizeof(W_Node
));
640 ptr
->left
= self
->nil
;
641 ptr
->right
= self
->nil
;
642 ptr
->parent
= self
->nil
;
644 rbTreeInsert(self
, ptr
);
654 WMSortBag(WMBag
*self
, WMCompareDataProc
*comparer
)
660 if (self
->count
== 0)
663 items
= wmalloc(sizeof(void*)*self
->count
);
666 tmp
= treeMinimum(self
->root
, self
->nil
);
667 while (tmp
!= self
->nil
) {
668 items
[i
++] = tmp
->data
;
669 tmp
= treeSuccessor(tmp
, self
->nil
);
672 qsort(&items
[0], self
->count
, sizeof(void*), comparer
);
675 tmp
= treeMinimum(self
->root
, self
->nil
);
676 while (tmp
!= self
->nil
) {
678 tmp
->data
= items
[i
++];
679 tmp
= treeSuccessor(tmp
, self
->nil
);
687 deleteTree(WMBag
*self
, W_Node
*node
)
689 if (node
== self
->nil
)
692 deleteTree(self
, node
->left
);
694 if (self
->destructor
)
695 self
->destructor(node
->data
);
697 deleteTree(self
, node
->right
);
704 WMEmptyBag(WMBag
*self
)
706 deleteTree(self
, self
->root
);
707 self
->root
= self
->nil
;
713 WMFreeBag(WMBag
*self
)
722 mapTree(W_Bag
*tree
, W_Node
*node
, void (*function
)(void*, void*), void *data
)
724 if (node
== tree
->nil
)
727 mapTree(tree
, node
->left
, function
, data
);
729 (*function
)(node
->data
, data
);
731 mapTree(tree
, node
->right
, function
, data
);
736 WMMapBag(WMBag
*self
, void (*function
)(void*, void*), void *data
)
738 mapTree(self
, self
->root
, function
, data
);
744 findInTree(W_Bag
*tree
, W_Node
*node
, WMMatchDataProc
*function
, void *cdata
)
748 if (node
== tree
->nil
)
751 index
= findInTree(tree
, node
->left
, function
, cdata
);
752 if (index
!= WBNotFound
)
755 if ((*function
)(node
->data
, cdata
)) {
759 return findInTree(tree
, node
->right
, function
, cdata
);
764 WMFindInBag(WMBag
*self
, WMMatchDataProc
*match
, void *cdata
)
766 return findInTree(self
, self
->root
, match
, cdata
);
771 WMBagFirst(WMBag
*self
, WMBagIterator
*ptr
)
775 node
= treeMinimum(self
->root
, self
->nil
);
777 if (node
== self
->nil
) {
788 WMBagLast(WMBag
*self
, WMBagIterator
*ptr
)
793 node
= treeMaximum(self
->root
, self
->nil
);
795 if (node
== self
->nil
) {
806 WMBagNext(WMBag
*self
, WMBagIterator
*ptr
)
813 node
= treeSuccessor(*ptr
, self
->nil
);
815 if (node
== self
->nil
) {
826 WMBagPrevious(WMBag
*self
, WMBagIterator
*ptr
)
833 node
= treePredecessor(*ptr
, self
->nil
);
835 if (node
== self
->nil
) {
846 WMBagIteratorAtIndex(WMBag
*self
, int index
, WMBagIterator
*ptr
)
850 node
= treeSearch(self
->root
, self
->nil
, index
);
852 if (node
== self
->nil
) {
863 WMBagIndexForIterator(WMBag
*bag
, WMBagIterator ptr
)
865 return ((W_Node
*)ptr
)->index
;