public static function getSequences(BinaryTreeNode $node)
 {
     $prefix = [$node->getData()];
     $left = $node->getLeft();
     $right = $node->getRight();
     if ($left === null && $right === null) {
         return [$prefix];
     }
     $leftSequences = $left !== null ? self::getSequences($left) : null;
     $rightSequences = $right !== null ? self::getSequences($right) : null;
     $sequences = [];
     if ($leftSequences === null) {
         foreach ($rightSequences as $rightSequence) {
             $sequences[] = array_merge($prefix, $rightSequence);
         }
         return $sequences;
     }
     if ($rightSequences === null) {
         foreach ($leftSequences as $leftSequence) {
             $sequences[] = array_merge($prefix, $leftSequence);
         }
         return $sequences;
     }
     // combine $leftSequences and $rightSequences in every possible way
     foreach ($leftSequences as $leftSequence) {
         foreach ($rightSequences as $rightSequence) {
             $mergedSequence = array_merge($leftSequence, $rightSequence);
             $orderings = self::getAllOrderings($mergedSequence);
             foreach ($orderings as $ordering) {
                 $sequences[] = array_merge($prefix, $ordering);
             }
         }
     }
     return $sequences;
 }
 public static function areTreesEqual(BinaryTreeNode $tree1, BinaryTreeNode $tree2)
 {
     if ($tree1->getData() !== $tree2->getData()) {
         return false;
     }
     $queue1 = [$tree1];
     $queue2 = [$tree2];
     while (!empty($queue1)) {
         $node1 = array_shift($queue1);
         $node2 = array_shift($queue2);
         $pairs = [[$node1->getLeft(), $node2->getLeft()], [$node1->getRight(), $node2->getRight()]];
         foreach ($pairs as $pair) {
             if ($pair[0] === null) {
                 if ($pair[1] !== null) {
                     return false;
                 }
             } elseif ($pair[1] === null) {
                 return false;
             } elseif ($pair[0]->getData() !== $pair[1]->getData()) {
                 return false;
             } else {
                 array_push($queue1, $pair[0]);
                 array_push($queue2, $pair[1]);
             }
         }
     }
     return true;
 }
 public static function isBinarySearchTree(BinaryTreeNode $node, $min = null, $max = null)
 {
     $left = $node->getLeft();
     $right = $node->getRight();
     $nodeValue = $node->getData();
     if ($left !== null) {
         $leftValue = $left->getData();
         if ($nodeValue < $leftValue) {
             return false;
         }
         if ($min !== null && $min > $leftValue) {
             return false;
         }
         if (!self::isBinarySearchTree($left, $min, $nodeValue)) {
             return false;
         }
     }
     if ($right !== null) {
         $rightValue = $right->getData();
         if ($nodeValue > $rightValue) {
             return false;
         }
         if ($max !== null && $max < $rightValue) {
             return false;
         }
         if (!self::isBinarySearchTree($right, $nodeValue, $max)) {
             return false;
         }
     }
     return true;
 }
 public function testBinaryTreeNode()
 {
     $node1 = new BinaryTreeNode('Dizzy');
     $this->assertEquals('Dizzy', $node1->getData());
     $this->assertEquals('Dizzy', (string) $node1);
     $node1->setData('Miles');
     $this->assertEquals('Miles', $node1->getData());
     $this->assertEquals('Miles', (string) $node1);
     $this->assertNull($node1->getLeft());
     $this->assertNull($node1->getRight());
     $node2 = new BinaryTreeNode('Cannonball');
     $node3 = new BinaryTreeNode('Coltrane');
     $node1->setLeft($node2);
     $node1->setRight($node3);
     $this->assertSame($node2, $node1->getLeft());
     $this->assertSame($node3, $node1->getRight());
 }
 public static function countPathsWithSum(BinaryTreeNode $node, $targetSum, array $breadCrumb = [])
 {
     $newBreadCrumb = array_merge($breadCrumb, [$node->getData()]);
     $resultCount = self::getPathSumCount($newBreadCrumb, $targetSum);
     $left = $node->getLeft();
     if ($left !== null) {
         $resultCount += self::countPathsWithSum($left, $targetSum, $newBreadCrumb);
     }
     $right = $node->getRight();
     if ($right !== null) {
         $resultCount += self::countPathsWithSum($right, $targetSum, $newBreadCrumb);
     }
     return $resultCount;
 }
 public static function countPathsWithSum(BinaryTreeNode $node = null, $targetSum, $runningSum = 0, array &$pathCountMap = [])
 {
     if ($node === null) {
         return 0;
     }
     $runningSum += $node->getData();
     $sum = $runningSum - $targetSum;
     $totalPaths = array_key_exists($sum, $pathCountMap) ? $pathCountMap[$sum] : 0;
     if ($runningSum === $targetSum) {
         $totalPaths++;
     }
     $pathCountMap[$runningSum] = (array_key_exists($runningSum, $pathCountMap) ? $pathCountMap[$runningSum] : 0) + 1;
     $totalPaths += self::countPathsWithSum($node->getLeft(), $targetSum, $runningSum, $pathCountMap);
     $totalPaths += self::countPathsWithSum($node->getRight(), $targetSum, $runningSum, $pathCountMap);
     $pathCountMap[$runningSum] -= 1;
     return $totalPaths;
 }