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 if (!WMPutInBag(self
, data
))
442 WMPutInBag(WMBag
*self
, void *item
)
446 ptr
= wmalloc(sizeof(W_Node
));
449 ptr
->index
= self
->count
;
450 ptr
->left
= self
->nil
;
451 ptr
->right
= self
->nil
;
452 ptr
->parent
= self
->nil
;
454 rbTreeInsert(self
, ptr
);
463 WMInsertInBag(WMBag
*self
, int index
, void *item
)
467 ptr
= wmalloc(sizeof(W_Node
));
471 ptr
->left
= self
->nil
;
472 ptr
->right
= self
->nil
;
473 ptr
->parent
= self
->nil
;
475 rbTreeInsert(self
, ptr
);
477 while ((ptr
= treeSuccessor(ptr
, self
->nil
)) != self
->nil
) {
489 WMRemoveFromBag(WMBag
*self
, void *item
)
491 W_Node
*ptr
= treeFind(self
->root
, self
->nil
, item
);
493 if (ptr
!= self
->nil
) {
498 tmp
= treeSuccessor(ptr
, self
->nil
);
499 while (tmp
!= self
->nil
) {
501 tmp
= treeSuccessor(tmp
, self
->nil
);
504 ptr
= rbTreeDelete(self
, ptr
);
505 if (self
->destructor
)
506 self
->destructor(ptr
->data
);
517 WMEraseFromBag(WMBag
*self
, int index
)
519 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
521 if (ptr
!= self
->nil
) {
525 ptr
= rbTreeDelete(self
, ptr
);
526 if (self
->destructor
)
527 self
->destructor(ptr
->data
);
530 wassertrv(self
->count
== 0||self
->root
->index
>= 0, 1);
540 WMDeleteFromBag(WMBag
*self
, int index
)
542 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
544 if (ptr
!= self
->nil
) {
549 tmp
= treeSuccessor(ptr
, self
->nil
);
550 while (tmp
!= self
->nil
) {
552 tmp
= treeSuccessor(tmp
, self
->nil
);
555 ptr
= rbTreeDelete(self
, ptr
);
556 if (self
->destructor
)
557 self
->destructor(ptr
->data
);
560 wassertrv(self
->count
== 0||self
->root
->index
>= 0, 1);
570 WMGetFromBag(WMBag
*self
, int index
)
574 node
= treeSearch(self
->root
, self
->nil
, index
);
575 if (node
!= self
->nil
)
583 WMGetFirstInBag(WMBag
*self
, void *item
)
587 node
= treeFind(self
->root
, self
->nil
, item
);
588 if (node
!= self
->nil
)
597 treeCount(W_Node
*root
, W_Node
*nil
, void *item
)
604 if (root
->data
== item
)
607 if (root
->left
!= nil
)
608 count
+= treeCount(root
->left
, nil
, item
);
610 if (root
->right
!= nil
)
611 count
+= treeCount(root
->right
, nil
, item
);
619 WMCountInBag(WMBag
*self
, void *item
)
621 return treeCount(self
->root
, self
->nil
, item
);
626 WMReplaceInBag(WMBag
*self
, int index
, void *item
)
628 W_Node
*ptr
= treeSearch(self
->root
, self
->nil
, index
);
633 ptr
= rbTreeDelete(self
, ptr
);
634 if (self
->destructor
)
635 self
->destructor(ptr
->data
);
637 } else if (ptr
!= self
->nil
) {
643 ptr
= wmalloc(sizeof(W_Node
));
647 ptr
->left
= self
->nil
;
648 ptr
->right
= self
->nil
;
649 ptr
->parent
= self
->nil
;
651 rbTreeInsert(self
, ptr
);
661 WMSortBag(WMBag
*self
, WMCompareDataProc
*comparer
)
667 if (self
->count
== 0)
670 items
= wmalloc(sizeof(void*)*self
->count
);
673 tmp
= treeMinimum(self
->root
, self
->nil
);
674 while (tmp
!= self
->nil
) {
675 items
[i
++] = tmp
->data
;
676 tmp
= treeSuccessor(tmp
, self
->nil
);
679 qsort(&items
[0], self
->count
, sizeof(void*), comparer
);
682 tmp
= treeMinimum(self
->root
, self
->nil
);
683 while (tmp
!= self
->nil
) {
685 tmp
->data
= items
[i
++];
686 tmp
= treeSuccessor(tmp
, self
->nil
);
696 deleteTree(WMBag
*self
, W_Node
*node
)
698 if (node
== self
->nil
)
701 deleteTree(self
, node
->left
);
703 if (self
->destructor
)
704 self
->destructor(node
->data
);
706 deleteTree(self
, node
->right
);
713 WMEmptyBag(WMBag
*self
)
715 deleteTree(self
, self
->root
);
716 self
->root
= self
->nil
;
722 WMFreeBag(WMBag
*self
)
733 mapTree(W_Bag
*tree
, W_Node
*node
, void (*function
)(void*, void*), void *data
)
735 if (node
== tree
->nil
)
738 mapTree(tree
, node
->left
, function
, data
);
740 (*function
)(node
->data
, data
);
742 mapTree(tree
, node
->right
, function
, data
);
747 WMMapBag(WMBag
*self
, void (*function
)(void*, void*), void *data
)
749 mapTree(self
, self
->root
, function
, data
);
755 findInTree(W_Bag
*tree
, W_Node
*node
, WMMatchDataProc
*function
, void *cdata
)
759 if (node
== tree
->nil
)
762 index
= findInTree(tree
, node
->left
, function
, cdata
);
763 if (index
!= WBNotFound
)
766 if ((*function
)(node
->data
, cdata
)) {
770 return findInTree(tree
, node
->right
, function
, cdata
);
775 WMFindInBag(WMBag
*self
, WMMatchDataProc
*match
, void *cdata
)
777 return findInTree(self
, self
->root
, match
, cdata
);
782 WMBagFirst(WMBag
*self
, WMBagIterator
*ptr
)
786 node
= treeMinimum(self
->root
, self
->nil
);
788 if (node
== self
->nil
) {
801 WMBagLast(WMBag
*self
, WMBagIterator
*ptr
)
806 node
= treeMaximum(self
->root
, self
->nil
);
808 if (node
== self
->nil
) {
821 WMBagNext(WMBag
*self
, WMBagIterator
*ptr
)
828 node
= treeSuccessor(*ptr
, self
->nil
);
830 if (node
== self
->nil
) {
843 WMBagPrevious(WMBag
*self
, WMBagIterator
*ptr
)
850 node
= treePredecessor(*ptr
, self
->nil
);
852 if (node
== self
->nil
) {
865 WMBagIteratorAtIndex(WMBag
*self
, int index
, WMBagIterator
*ptr
)
869 node
= treeSearch(self
->root
, self
->nil
, index
);
871 if (node
== self
->nil
) {
882 WMBagIndexForIterator(WMBag
*bag
, WMBagIterator ptr
)
884 return ((W_Node
*)ptr
)->index
;