7 public enum TreePrintStyle { inOrder, postOrder, preOrder, depthOrder };
9 public void strcatf(char * string, char * format, ...)
12 va_start(args, format);
13 vsprintf(string+strlen(string),format,args);
17 public class BTNode : struct
22 BTNode parent, left, right;
25 void OnSerialize(IOChannel channel)
30 channel.Serialize(truth);
31 channel.Serialize(key);
32 channel.Serialize(left);
33 channel.Serialize(right);
38 channel.Serialize(nothing);
42 void OnUnserialize(IOChannel channel)
45 channel.Unserialize(truth);
48 // TODO: Fix typed_object issues
49 this = eInstance_New(class(BTNode));
50 channel.Unserialize(key);
51 channel.Unserialize(left);
52 if(left) { left.parent = (void *)this; }
53 channel.Unserialize(right);
54 if(right) { right.parent = (void *)this; }
55 depth = ((BTNode)(void *)this).depthProp;
69 if(parent && this == parent.right)
82 BTNode right = this.right;
87 BTNode parent = this.parent;
88 if(parent && this == parent.left)
97 property BTNode minimum
99 get { while(left) this = left; return this; }
102 property BTNode maximum
104 get { while(right) this = right; return this; }
109 get { return 1 + (left ? left.count : 0) + (right ? right.count : 0); }
111 property int depthProp
115 int leftDepth = left ? (left.depthProp+1) : 0;
116 int rightDepth = right ? (right.depthProp+1) : 0;
117 return Max(leftDepth, rightDepth);
122 void Free(void (*FreeKey)(void * key))
124 if (left) left.Free(FreeKey);
125 if (right) right.Free(FreeKey);
126 if(FreeKey) FreeKey((void *)key);
130 bool Add(BinaryTree tree, BTNode node)
132 uint newKey = node.key;
135 //int result = (newKey > key) ? 1 : ((newKey < key) ? - 1 : 0);
136 int result = tree.CompareKey(tree, newKey, key);
140 // sprintf("Adding item already in binary tree\n");
155 for(n = this; n; n = n.parent)
157 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
158 if(newDepth == n.depth)
177 for(n = this; n; n = n.parent)
179 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
180 if(newDepth == n.depth)
191 bool FindNode(BTNode node)
195 else if(left && left.FindNode(node))
197 else if(right && right.FindNode(node))
202 BTNode Find(BinaryTree tree, uint key)
206 // int result = (key > this.key) ? 1 : ((key < this.key) ? - 1 : 0);
207 int result = tree.CompareKey(tree, key, this.key);
218 public BTNode FindString(char * key)
224 result = strcmp(key, (char *)this.key);
225 else if(key && !this.key)
227 else if(!key && this.key)
242 public BTNode FindPrefix(char * key)
244 BTNode subString = null;
245 int len = key ? strlen(key) : 0;
250 result = strcmp(key, (char *)this.key);
251 else if(key && !this.key)
253 else if(!key && this.key)
260 if(!strncmp(key, (char *)this.key, len))
275 BTNode FindAll(uint key)
277 BTNode result = null;
278 if(this.key == key) result = this;
279 if(!result && left) result = left.FindAll(key);
280 if(!result && right) result = right.FindAll(key);
284 void RemoveSwap(BTNode swap)
288 swap.left.parent = swap.parent;
289 if(swap == swap.parent.left)
290 swap.parent.left = swap.left;
291 else if(swap == swap.parent.right)
292 swap.parent.right = swap.left;
297 swap.right.parent = swap.parent;
298 if(swap == swap.parent.left)
299 swap.parent.left = swap.right;
300 else if(swap == swap.parent.right)
301 swap.parent.right = swap.right;
305 if(swap == swap.parent.left) swap.parent.left = null;
306 else if(swap == swap.parent.right) swap.parent.right = null;
310 for(n = swap.parent; n; n = n.parent)
312 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
313 if(newDepth == n.depth)
332 swap.parent = parent;
337 if(this == parent.left) parent.left = swap;
338 else if(this == parent.right) parent.right = swap;
342 BTNode RemoveSwapLeft()
344 BTNode swap = left ? left.maximum : right;
345 BTNode swapParent = null;
346 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
349 if(this == parent.left) parent.left = null;
350 else if(this == parent.right) parent.right = null;
354 for(n = swap ? swap : parent; n; n = n.parent)
356 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
357 if(newDepth == n.depth && n != swap)
362 if(swapParent && swapParent != this)
363 return swapParent.Rebalance();
365 return swap.Rebalance();
367 return parent.Rebalance();
372 BTNode RemoveSwapRight()
375 BTNode swap = right ? right.minimum : left;
376 BTNode swapParent = null;
377 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
380 if(this == parent.left) parent.left = null;
381 else if(this == parent.right) parent.right = null;
385 for(n = swap ? swap : parent; n; n = n.parent)
387 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
389 if(newDepth != n.depthProp)
392 if(newDepth == n.depth && n != swap)
397 if(swapParent && swapParent != this)
398 result = swapParent.Rebalance();
400 result = swap.Rebalance();
402 result = parent.Rebalance();
408 property int balanceFactor
412 int leftDepth = left ? (left.depth+1) : 0;
413 int rightDepth = right ? (right.depth+1) : 0;
414 return rightDepth - leftDepth;
422 int factor = balanceFactor;
425 if(left.balanceFactor == 1)
432 if(right.balanceFactor == -1)
444 void SingleRotateRight()
448 if(this == parent.left)
450 else if(this == parent.right)
453 left.parent = parent;
456 if(left) left.parent = this;
459 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
460 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
463 for(n = parent.parent; n; n = n.parent)
465 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
467 if(newDepth != n.depthProp)
470 if(newDepth == n.depth)
477 void SingleRotateLeft()
481 if(this == parent.right)
482 parent.right = right;
483 else if(this == parent.left)
486 right.parent = parent;
489 if(right) right.parent = this;
492 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
493 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
496 for(n = parent.parent; n; n = n.parent)
498 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
500 if(newDepth != n.depthProp)
503 if(newDepth == n.depth)
510 void DoubleRotateRight()
512 left.SingleRotateLeft();
516 void DoubleRotateLeft()
518 right.SingleRotateRight();
524 char * Print(char * output, TreePrintStyle tps)
532 if(tps == preOrder) strcatf(output, "%d ", key);
534 if (left) left.Print(output, tps);
536 if(tps == inOrder) strcatf(output, "%d ", key);
538 if (right) right.Print(output, tps);
540 if(tps == postOrder) strcatf(output, "%d ", key);
546 int maxDepth = depth;
549 for(curDepth = 0; curDepth <= maxDepth; curDepth++)
552 for(c = 0; c<((1<<(maxDepth - curDepth))-1) * NUMSIZE / 2; c++)
554 PrintDepth(output, curDepth, 0, maxDepth, true);
555 strcat(output, "\n");
563 void PrintDepth(char * output, int wantedDepth, int curDepth, int maxDepth, bool last)
566 if(wantedDepth == curDepth)
568 char nodeString[10] = "";
572 sprintf(nodeString, "%d", key);
574 len = strlen(nodeString);
575 for(c = 0; c<(NUMSIZE - len)/2; c++)
578 strcat(output, nodeString);
579 for(c = len; c<NUMSIZE; c++)
582 if(curDepth && !last)
584 for(c = 0; c<((1<<(maxDepth-curDepth)) - 1) * NUMSIZE; c++)
588 else if(curDepth <= maxDepth)
590 (this ? left : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last && this && !right);
591 (this ? right : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last);
595 bool Check(BinaryTree tree)
598 // Now get the height of each subtree
599 int leftHeight = left ? left.depthProp+1 : 0;
600 int rightHeight = right ? right.depthProp+1 : 0;
602 // Verify that AVL tree property is satisfied
603 int diffHeight = rightHeight - leftHeight;
607 if(left.parent != this)
609 printf("Parent not set properly at node %d\n", left.key);
612 valid *= left.Check(tree);
616 if(right.parent != this)
618 printf("Parent not set properly at node %d\n", right.key);
621 valid *= right.Check(tree);
624 if(depth != depthProp)
626 printf("Depth value at node %d (%d) doesn't match depth property (%d)\n", key, depth, depthProp);
630 if (diffHeight < -1 || diffHeight > 1)
633 printf("Height difference is %d at node %d\n", diffHeight, key);
636 // Verify that balance-factor is correct
637 if (diffHeight != balanceFactor)
640 printf("Height difference %d doesnt match balance-factor of %d at node \n", diffHeight, balanceFactor, key);
643 // Verify that search-tree property is satisfied
644 if (left && tree.CompareKey(tree, left.key, key) > 0)
647 printf("Node %d is *smaller* than left subtree %d\n", key, left.key);
649 if (right && tree.CompareKey(tree, right.key, key) < 0)
652 printf("Node %d is *greater* than right subtree %d\n", key, right.key);
658 // TODO: WHY CAN'T WE HAVE THIS ABOVE?
660 public class StringBTNode : struct // BTNode
665 StringBTNode parent, left, right;
668 void OnSerialize(IOChannel channel)
673 channel.Serialize(truth);
674 channel.Serialize(key);
675 channel.Serialize(left);
676 channel.Serialize(right);
681 channel.Serialize(nothing);
685 void OnUnserialize(IOChannel channel)
688 channel.Unserialize(truth);
691 // TODO: Fix typed_object issues
692 this = eInstance_New(class(StringBTNode));
693 channel.Unserialize(key);
694 channel.Unserialize(left);
695 if(left) { left.parent = (void *)this; }
696 channel.Unserialize(right);
697 if(right) { right.parent = (void *)this; }
699 // TODO: Precomp errors without extra brackets
700 depth = ((BTNode)((void *)this)).depthProp;