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)
222 int result = strcmp(key, (char *)this.key);
233 BTNode FindAll(uint key)
235 BTNode result = null;
236 if(this.key == key) result = this;
237 if(!result && left) result = left.FindAll(key);
238 if(!result && right) result = right.FindAll(key);
242 void RemoveSwap(BTNode swap)
246 swap.left.parent = swap.parent;
247 if(swap == swap.parent.left)
248 swap.parent.left = swap.left;
249 else if(swap == swap.parent.right)
250 swap.parent.right = swap.left;
255 swap.right.parent = swap.parent;
256 if(swap == swap.parent.left)
257 swap.parent.left = swap.right;
258 else if(swap == swap.parent.right)
259 swap.parent.right = swap.right;
263 if(swap == swap.parent.left) swap.parent.left = null;
264 else if(swap == swap.parent.right) swap.parent.right = null;
268 for(n = swap.parent; n; n = n.parent)
270 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
271 if(newDepth == n.depth)
290 swap.parent = parent;
295 if(this == parent.left) parent.left = swap;
296 else if(this == parent.right) parent.right = swap;
300 BTNode RemoveSwapLeft()
302 BTNode swap = left ? left.maximum : right;
303 BTNode swapParent = null;
304 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
307 if(this == parent.left) parent.left = null;
308 else if(this == parent.right) parent.right = null;
312 for(n = swap ? swap : parent; n; n = n.parent)
314 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
315 if(newDepth == n.depth && n != swap)
320 if(swapParent && swapParent != this)
321 return swapParent.Rebalance();
323 return swap.Rebalance();
325 return parent.Rebalance();
330 BTNode RemoveSwapRight()
333 BTNode swap = right ? right.minimum : left;
334 BTNode swapParent = null;
335 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
338 if(this == parent.left) parent.left = null;
339 else if(this == parent.right) parent.right = null;
343 for(n = swap ? swap : parent; n; n = n.parent)
345 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
347 if(newDepth != n.depthProp)
350 if(newDepth == n.depth && n != swap)
355 if(swapParent && swapParent != this)
356 result = swapParent.Rebalance();
358 result = swap.Rebalance();
360 result = parent.Rebalance();
366 property int balanceFactor
370 int leftDepth = left ? (left.depth+1) : 0;
371 int rightDepth = right ? (right.depth+1) : 0;
372 return rightDepth - leftDepth;
380 int factor = balanceFactor;
383 if(left.balanceFactor == 1)
390 if(right.balanceFactor == -1)
402 void SingleRotateRight()
406 if(this == parent.left)
408 else if(this == parent.right)
411 left.parent = parent;
414 if(left) left.parent = this;
417 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
418 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
421 for(n = parent.parent; n; n = n.parent)
423 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
425 if(newDepth != n.depthProp)
428 if(newDepth == n.depth)
435 void SingleRotateLeft()
439 if(this == parent.right)
440 parent.right = right;
441 else if(this == parent.left)
444 right.parent = parent;
447 if(right) right.parent = this;
450 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
451 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
454 for(n = parent.parent; n; n = n.parent)
456 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
458 if(newDepth != n.depthProp)
461 if(newDepth == n.depth)
468 void DoubleRotateRight()
470 left.SingleRotateLeft();
474 void DoubleRotateLeft()
476 right.SingleRotateRight();
482 char * Print(char * output, TreePrintStyle tps)
490 if(tps == preOrder) strcatf(output, "%d ", key);
492 if (left) left.Print(output, tps);
494 if(tps == inOrder) strcatf(output, "%d ", key);
496 if (right) right.Print(output, tps);
498 if(tps == postOrder) strcatf(output, "%d ", key);
504 int maxDepth = depth;
507 for(curDepth = 0; curDepth <= maxDepth; curDepth++)
510 for(c = 0; c<((1<<(maxDepth - curDepth))-1) * NUMSIZE / 2; c++)
512 PrintDepth(output, curDepth, 0, maxDepth, true);
513 strcat(output, "\n");
521 void PrintDepth(char * output, int wantedDepth, int curDepth, int maxDepth, bool last)
524 if(wantedDepth == curDepth)
526 char nodeString[10] = "";
530 sprintf(nodeString, "%d", key);
532 len = strlen(nodeString);
533 for(c = 0; c<(NUMSIZE - len)/2; c++)
536 strcat(output, nodeString);
537 for(c = len; c<NUMSIZE; c++)
540 if(curDepth && !last)
542 for(c = 0; c<((1<<(maxDepth-curDepth)) - 1) * NUMSIZE; c++)
546 else if(curDepth <= maxDepth)
548 (this ? left : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last && this && !right);
549 (this ? right : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last);
553 bool Check(BinaryTree tree)
556 // Now get the height of each subtree
557 int leftHeight = left ? left.depthProp+1 : 0;
558 int rightHeight = right ? right.depthProp+1 : 0;
560 // Verify that AVL tree property is satisfied
561 int diffHeight = rightHeight - leftHeight;
565 if(left.parent != this)
567 printf("Parent not set properly at node %d\n", left.key);
570 valid *= left.Check(tree);
574 if(right.parent != this)
576 printf("Parent not set properly at node %d\n", right.key);
579 valid *= right.Check(tree);
582 if(depth != depthProp)
584 printf("Depth value at node %d (%d) doesn't match depth property (%d)\n", key, depth, depthProp);
588 if (diffHeight < -1 || diffHeight > 1)
591 printf("Height difference is %d at node %d\n", diffHeight, key);
594 // Verify that balance-factor is correct
595 if (diffHeight != balanceFactor)
598 printf("Height difference %d doesnt match balance-factor of %d at node \n", diffHeight, balanceFactor, key);
601 // Verify that search-tree property is satisfied
602 if (left && tree.CompareKey(tree, left.key, key) > 0)
605 printf("Node %d is *smaller* than left subtree %d\n", key, left.key);
607 if (right && tree.CompareKey(tree, right.key, key) < 0)
610 printf("Node %d is *greater* than right subtree %d\n", key, right.key);
616 // TODO: WHY CAN'T WE HAVE THIS ABOVE?
618 public class StringBTNode : struct // BTNode
623 StringBTNode parent, left, right;
626 void OnSerialize(IOChannel channel)
631 channel.Serialize(truth);
632 channel.Serialize(key);
633 channel.Serialize(left);
634 channel.Serialize(right);
639 channel.Serialize(nothing);
643 void OnUnserialize(IOChannel channel)
646 channel.Unserialize(truth);
649 // TODO: Fix typed_object issues
650 this = eInstance_New(class(StringBTNode));
651 channel.Unserialize(key);
652 channel.Unserialize(left);
653 if(left) { left.parent = (void *)this; }
654 channel.Unserialize(right);
655 if(right) { right.parent = (void *)this; }
657 // TODO: Precomp errors without extra brackets
658 depth = ((BTNode)((void *)this)).depthProp;