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;