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 BTNode FindAll(uint key)
244 BTNode result = null;
245 if(this.key == key) result = this;
246 if(!result && left) result = left.FindAll(key);
247 if(!result && right) result = right.FindAll(key);
251 void RemoveSwap(BTNode swap)
255 swap.left.parent = swap.parent;
256 if(swap == swap.parent.left)
257 swap.parent.left = swap.left;
258 else if(swap == swap.parent.right)
259 swap.parent.right = swap.left;
264 swap.right.parent = swap.parent;
265 if(swap == swap.parent.left)
266 swap.parent.left = swap.right;
267 else if(swap == swap.parent.right)
268 swap.parent.right = swap.right;
272 if(swap == swap.parent.left) swap.parent.left = null;
273 else if(swap == swap.parent.right) swap.parent.right = null;
277 for(n = swap.parent; n; n = n.parent)
279 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
280 if(newDepth == n.depth)
299 swap.parent = parent;
304 if(this == parent.left) parent.left = swap;
305 else if(this == parent.right) parent.right = swap;
309 BTNode RemoveSwapLeft()
311 BTNode swap = left ? left.maximum : right;
312 BTNode swapParent = null;
313 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
316 if(this == parent.left) parent.left = null;
317 else if(this == parent.right) parent.right = null;
321 for(n = swap ? swap : parent; n; n = n.parent)
323 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
324 if(newDepth == n.depth && n != swap)
329 if(swapParent && swapParent != this)
330 return swapParent.Rebalance();
332 return swap.Rebalance();
334 return parent.Rebalance();
339 BTNode RemoveSwapRight()
342 BTNode swap = right ? right.minimum : left;
343 BTNode swapParent = null;
344 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
347 if(this == parent.left) parent.left = null;
348 else if(this == parent.right) parent.right = null;
352 for(n = swap ? swap : parent; n; n = n.parent)
354 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
356 if(newDepth != n.depthProp)
359 if(newDepth == n.depth && n != swap)
364 if(swapParent && swapParent != this)
365 result = swapParent.Rebalance();
367 result = swap.Rebalance();
369 result = parent.Rebalance();
375 property int balanceFactor
379 int leftDepth = left ? (left.depth+1) : 0;
380 int rightDepth = right ? (right.depth+1) : 0;
381 return rightDepth - leftDepth;
389 int factor = balanceFactor;
392 if(left.balanceFactor == 1)
399 if(right.balanceFactor == -1)
411 void SingleRotateRight()
415 if(this == parent.left)
417 else if(this == parent.right)
420 left.parent = parent;
423 if(left) left.parent = this;
426 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
427 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
430 for(n = parent.parent; n; n = n.parent)
432 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
434 if(newDepth != n.depthProp)
437 if(newDepth == n.depth)
444 void SingleRotateLeft()
448 if(this == parent.right)
449 parent.right = right;
450 else if(this == parent.left)
453 right.parent = parent;
456 if(right) right.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 DoubleRotateRight()
479 left.SingleRotateLeft();
483 void DoubleRotateLeft()
485 right.SingleRotateRight();
491 char * Print(char * output, TreePrintStyle tps)
499 if(tps == preOrder) strcatf(output, "%d ", key);
501 if (left) left.Print(output, tps);
503 if(tps == inOrder) strcatf(output, "%d ", key);
505 if (right) right.Print(output, tps);
507 if(tps == postOrder) strcatf(output, "%d ", key);
513 int maxDepth = depth;
516 for(curDepth = 0; curDepth <= maxDepth; curDepth++)
519 for(c = 0; c<((1<<(maxDepth - curDepth))-1) * NUMSIZE / 2; c++)
521 PrintDepth(output, curDepth, 0, maxDepth, true);
522 strcat(output, "\n");
530 void PrintDepth(char * output, int wantedDepth, int curDepth, int maxDepth, bool last)
533 if(wantedDepth == curDepth)
535 char nodeString[10] = "";
539 sprintf(nodeString, "%d", key);
541 len = strlen(nodeString);
542 for(c = 0; c<(NUMSIZE - len)/2; c++)
545 strcat(output, nodeString);
546 for(c = len; c<NUMSIZE; c++)
549 if(curDepth && !last)
551 for(c = 0; c<((1<<(maxDepth-curDepth)) - 1) * NUMSIZE; c++)
555 else if(curDepth <= maxDepth)
557 (this ? left : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last && this && !right);
558 (this ? right : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last);
562 bool Check(BinaryTree tree)
565 // Now get the height of each subtree
566 int leftHeight = left ? left.depthProp+1 : 0;
567 int rightHeight = right ? right.depthProp+1 : 0;
569 // Verify that AVL tree property is satisfied
570 int diffHeight = rightHeight - leftHeight;
574 if(left.parent != this)
576 printf("Parent not set properly at node %d\n", left.key);
579 valid *= left.Check(tree);
583 if(right.parent != this)
585 printf("Parent not set properly at node %d\n", right.key);
588 valid *= right.Check(tree);
591 if(depth != depthProp)
593 printf("Depth value at node %d (%d) doesn't match depth property (%d)\n", key, depth, depthProp);
597 if (diffHeight < -1 || diffHeight > 1)
600 printf("Height difference is %d at node %d\n", diffHeight, key);
603 // Verify that balance-factor is correct
604 if (diffHeight != balanceFactor)
607 printf("Height difference %d doesnt match balance-factor of %d at node \n", diffHeight, balanceFactor, key);
610 // Verify that search-tree property is satisfied
611 if (left && tree.CompareKey(tree, left.key, key) > 0)
614 printf("Node %d is *smaller* than left subtree %d\n", key, left.key);
616 if (right && tree.CompareKey(tree, right.key, key) < 0)
619 printf("Node %d is *greater* than right subtree %d\n", key, right.key);
625 // TODO: WHY CAN'T WE HAVE THIS ABOVE?
627 public class StringBTNode : struct // BTNode
632 StringBTNode parent, left, right;
635 void OnSerialize(IOChannel channel)
640 channel.Serialize(truth);
641 channel.Serialize(key);
642 channel.Serialize(left);
643 channel.Serialize(right);
648 channel.Serialize(nothing);
652 void OnUnserialize(IOChannel channel)
655 channel.Unserialize(truth);
658 // TODO: Fix typed_object issues
659 this = eInstance_New(class(StringBTNode));
660 channel.Unserialize(key);
661 channel.Unserialize(left);
662 if(left) { left.parent = (void *)this; }
663 channel.Unserialize(right);
664 if(right) { right.parent = (void *)this; }
666 // TODO: Precomp errors without extra brackets
667 depth = ((BTNode)((void *)this)).depthProp;