7 public enum TreePrintStyle { inOrder, postOrder, preOrder, depthOrder };
9 // WARNING: This function has no boundary check!
10 public void strcatf(char * string, const char * format, ...)
13 va_start(args, format);
14 vsprintf(string+strlen(string),format,args);
18 public class BTNode : struct
23 BTNode parent, left, right;
26 void OnSerialize(IOChannel channel)
31 channel.Serialize(truth);
32 channel.Serialize((uint)key); // Serialize/Deserialize as 32 bit for compatibility (e.g. EDB)
33 channel.Serialize(left);
34 channel.Serialize(right);
39 channel.Serialize(nothing);
43 void OnUnserialize(IOChannel channel)
46 channel.Unserialize(truth);
49 // TODO: Fix typed_object issues
50 this = eInstance_New(class(BTNode));
51 { uint k; channel.Unserialize(k); key = k; }
52 channel.Unserialize(left);
53 if(left) { left.parent = this; }
54 channel.Unserialize(right);
55 if(right) { right.parent = this; }
56 depth = ((BTNode)this).depthProp;
70 if(parent && this == parent.right)
83 BTNode right = this.right;
88 BTNode parent = this.parent;
89 if(parent && this == parent.left)
98 property BTNode minimum
100 get { while(left) this = left; return this; }
103 property BTNode maximum
105 get { while(right) this = right; return this; }
110 get { return 1 + (left ? left.count : 0) + (right ? right.count : 0); }
112 property int depthProp
116 int leftDepth = left ? (left.depthProp+1) : 0;
117 int rightDepth = right ? (right.depthProp+1) : 0;
118 return Max(leftDepth, rightDepth);
123 void Free(void (*FreeKey)(void * key))
125 if (left) left.Free(FreeKey);
126 if (right) right.Free(FreeKey);
127 if(FreeKey) FreeKey((void *)key);
131 bool Add(BinaryTree tree, BTNode node)
133 uintptr newKey = node.key;
136 //int result = (newKey > key) ? 1 : ((newKey < key) ? - 1 : 0);
137 int result = tree.CompareKey(tree, newKey, key);
141 // sprintf("Adding item already in binary tree\n");
156 for(n = this; n; n = n.parent)
158 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
159 if(newDepth == n.depth)
178 for(n = this; n; n = n.parent)
180 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
181 if(newDepth == n.depth)
192 bool FindNode(BTNode node)
196 else if(left && left.FindNode(node))
198 else if(right && right.FindNode(node))
203 BTNode Find(BinaryTree tree, uintptr key)
207 // int result = (key > this.key) ? 1 : ((key < this.key) ? - 1 : 0);
208 int result = tree.CompareKey(tree, key, this.key);
219 public BTNode FindString(const char * key)
225 result = strcmp(key, (const char *)this.key);
226 else if(key && !this.key)
228 else if(!key && this.key)
243 public BTNode FindPrefix(const char * key)
245 BTNode subString = null;
246 int len = key ? strlen(key) : 0;
251 result = strcmp(key, (const char *)this.key);
252 else if(key && !this.key)
254 else if(!key && this.key)
261 if(!strncmp(key, (const char *)this.key, len))
276 BTNode FindAll(uintptr key)
278 BTNode result = null;
279 if(this.key == key) result = this;
280 if(!result && left) result = left.FindAll(key);
281 if(!result && right) result = right.FindAll(key);
285 void RemoveSwap(BTNode swap)
289 swap.left.parent = swap.parent;
290 if(swap == swap.parent.left)
291 swap.parent.left = swap.left;
292 else if(swap == swap.parent.right)
293 swap.parent.right = swap.left;
298 swap.right.parent = swap.parent;
299 if(swap == swap.parent.left)
300 swap.parent.left = swap.right;
301 else if(swap == swap.parent.right)
302 swap.parent.right = swap.right;
306 if(swap == swap.parent.left) swap.parent.left = null;
307 else if(swap == swap.parent.right) swap.parent.right = null;
311 for(n = swap.parent; n; n = n.parent)
313 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
314 if(newDepth == n.depth)
333 swap.parent = parent;
338 if(this == parent.left) parent.left = swap;
339 else if(this == parent.right) parent.right = swap;
343 BTNode RemoveSwapLeft()
345 BTNode swap = left ? left.maximum : right;
346 BTNode swapParent = null;
347 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
350 if(this == parent.left) parent.left = null;
351 else if(this == parent.right) parent.right = null;
355 for(n = swap ? swap : parent; n; n = n.parent)
357 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
358 if(newDepth == n.depth && n != swap)
363 if(swapParent && swapParent != this)
364 return swapParent.Rebalance();
366 return swap.Rebalance();
368 return parent.Rebalance();
373 BTNode RemoveSwapRight()
376 BTNode swap = right ? right.minimum : left;
377 BTNode swapParent = null;
378 if(swap) { swapParent = swap.parent; RemoveSwap(swap); }
381 if(this == parent.left) parent.left = null;
382 else if(this == parent.right) parent.right = null;
386 for(n = swap ? swap : parent; n; n = n.parent)
388 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
390 if(newDepth != n.depthProp)
393 if(newDepth == n.depth && n != swap)
398 if(swapParent && swapParent != this)
399 result = swapParent.Rebalance();
401 result = swap.Rebalance();
403 result = parent.Rebalance();
409 property int balanceFactor
413 int leftDepth = left ? (left.depth+1) : 0;
414 int rightDepth = right ? (right.depth+1) : 0;
415 return rightDepth - leftDepth;
423 int factor = balanceFactor;
426 if(left.balanceFactor == 1)
433 if(right.balanceFactor == -1)
445 void SingleRotateRight()
449 if(this == parent.left)
451 else if(this == parent.right)
454 left.parent = parent;
457 if(left) left.parent = this;
460 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
461 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
464 for(n = parent.parent; n; n = n.parent)
466 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
468 if(newDepth != n.depthProp)
471 if(newDepth == n.depth)
478 void SingleRotateLeft()
482 if(this == parent.right)
483 parent.right = right;
484 else if(this == parent.left)
487 right.parent = parent;
490 if(right) right.parent = this;
493 depth = Max(left ? (left.depth+1) : 0, right ? (right.depth+1) : 0);
494 parent.depth = Max(parent.left ? (parent.left.depth+1) : 0, parent.right ? (parent.right.depth+1) : 0);
497 for(n = parent.parent; n; n = n.parent)
499 int newDepth = Max(n.left ? (n.left.depth+1) : 0, n.right ? (n.right.depth+1) : 0);
501 if(newDepth != n.depthProp)
504 if(newDepth == n.depth)
511 void DoubleRotateRight()
513 left.SingleRotateLeft();
517 void DoubleRotateLeft()
519 right.SingleRotateRight();
525 char * Print(char * output, TreePrintStyle tps)
533 if(tps == preOrder) strcatf(output, "%d ", key);
535 if (left) left.Print(output, tps);
537 if(tps == inOrder) strcatf(output, "%d ", key);
539 if (right) right.Print(output, tps);
541 if(tps == postOrder) strcatf(output, "%d ", key);
547 int maxDepth = depth;
550 for(curDepth = 0; curDepth <= maxDepth; curDepth++)
553 for(c = 0; c<((1<<(maxDepth - curDepth))-1) * NUMSIZE / 2; c++)
555 PrintDepth(output, curDepth, 0, maxDepth, true);
556 strcat(output, "\n");
564 void PrintDepth(char * output, int wantedDepth, int curDepth, int maxDepth, bool last)
567 if(wantedDepth == curDepth)
569 char nodeString[10] = "";
573 sprintf(nodeString, "%d", (int)key);
575 len = strlen(nodeString);
576 for(c = 0; c<(NUMSIZE - len)/2; c++)
579 strcat(output, nodeString);
580 for(c = len; c<NUMSIZE; c++)
583 if(curDepth && !last)
585 for(c = 0; c<((1<<(maxDepth-curDepth)) - 1) * NUMSIZE; c++)
589 else if(curDepth <= maxDepth)
591 (this ? left : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last && this && !right);
592 (this ? right : (BTNode)null).PrintDepth(output, wantedDepth, curDepth+1, maxDepth, last);
596 bool Check(BinaryTree tree)
599 // Now get the height of each subtree
600 int leftHeight = left ? left.depthProp+1 : 0;
601 int rightHeight = right ? right.depthProp+1 : 0;
603 // Verify that AVL tree property is satisfied
604 int diffHeight = rightHeight - leftHeight;
608 if(left.parent != this)
610 printf("Parent not set properly at node %d\n", (int)left.key);
613 valid *= left.Check(tree);
617 if(right.parent != this)
619 printf("Parent not set properly at node %d\n", (int)right.key);
622 valid *= right.Check(tree);
625 if(depth != depthProp)
627 printf("Depth value at node %d (%d) doesn't match depth property (%d)\n", (int)key, depth, depthProp);
631 if (diffHeight < -1 || diffHeight > 1)
634 printf("Height difference is %d at node %d\n", diffHeight, (int)key);
637 // Verify that balance-factor is correct
638 if (diffHeight != balanceFactor)
641 printf("Height difference %d doesnt match balance-factor of %d at node %d\n", diffHeight, balanceFactor, (int)key);
644 // Verify that search-tree property is satisfied
645 if (left && tree.CompareKey(tree, left.key, key) > 0)
648 printf("Node %d is *smaller* than left subtree %d\n", (int)key, (int)left.key);
650 if (right && tree.CompareKey(tree, right.key, key) < 0)
653 printf("Node %d is *greater* than right subtree %d\n", (int)key, (int)right.key);
659 public class StringBTNode : struct // BTNode
664 StringBTNode parent, left, right;
667 void OnSerialize(IOChannel channel)
672 channel.Serialize(truth);
673 channel.Serialize(key);
674 channel.Serialize(left);
675 channel.Serialize(right);
680 channel.Serialize(nothing);
684 void OnUnserialize(IOChannel channel)
687 channel.Unserialize(truth);
691 channel.Unserialize(key);
692 channel.Unserialize(left);
693 if(left) { left.parent = this; }
694 channel.Unserialize(right);
695 if(right) { right.parent = this; }
697 depth = ((BTNode)this).depthProp;