diff --git a/Stdlib/Graph/BinaryTree.php b/Stdlib/Graph/BinaryTree.php index 4f481ea45..bad8940e0 100644 --- a/Stdlib/Graph/BinaryTree.php +++ b/Stdlib/Graph/BinaryTree.php @@ -46,11 +46,11 @@ class BinaryTree extends Tree } public function getLeft() { - return $this->nodes[0]; + return $this->nodes[0] ?? null; } public function getRight() { - return $this->nodes[1]; + return $this->nodes[1] ?? null; } public function setLeft(BinaryTree $left) { @@ -61,7 +61,80 @@ class BinaryTree extends Tree $this->nodes[1] = $right; } - public function inOrder() { - + public function preOrder(\Closure $callback) { + if(count($this->nodes) === 0) { + return; + } + + $callback($this); + $this->nodes[0]->inOrder($callback); + $this->nodes[1]->inOrder($callback); + } + + public function inOrder(\Closure $callback) { + if(count($this->nodes) === 0) { + return; + } + + $this->nodes[0]->inOrder($callback); + $callback($this); + $this->nodes[1]->inOrder($callback); + } + + public function postOrder(\Closure $callback) { + if(count($this->nodes) === 0) { + return; + } + + $this->nodes[0]->inOrder($callback); + $this->nodes[1]->inOrder($callback); + $callback($this); + } + + private function getVerticalOrder(int $horizontalDistance = 0, array &$order) + { + if(!isset($order[$horizontalDistance])) { + $order[$horizontalDistance] = []; + } + + $order[$horizontalDistance][] = $this; + + if(isset($this->nodes[0])) { + $this->nodes[0]->getVerticalOrder($horizontalDistance-1, $order); + } + + if(isset($this->nodes[1])) { + $this->nodes[1]->getVerticalOrder($horizontalDistance+1, $order); + } + } + + public function verticalOrder(\Closure $callback) + { + $order = []; + $this->getVerticalOrder(0, $order); + + foreach($order as $level) { + foreach($level as $node) { + $callback($node); + } + } + } + + public function isSymmetric() : bool { + // todo: compare values? true symmetry requires the values to be the same + if(isset($this->nodes[0]) && isset($this->nodes[1])) { + return isSymmetric($this->nodes[0], $this->nodes[1]); + } + + return false; + } + + public function symmetric(BinaryTree $tree1, BinaryTree $tree2) : bool { + // todo: compare values? true symmetry requires the values to be the same + if(($tree1 !== null && $tree2 !== null) || $tree1 === $tree2) { + return isSymmetric($tree1->getLeft(), $tree1->getRight()) && isSymmetric($tree2->getRight(), $tree2->getLeft()); + } + + return false; } } \ No newline at end of file diff --git a/Stdlib/Graph/Tree.php b/Stdlib/Graph/Tree.php index 4d1a29e36..82514b0cc 100644 --- a/Stdlib/Graph/Tree.php +++ b/Stdlib/Graph/Tree.php @@ -32,6 +32,18 @@ class Tree extends Graph { protected $nodes = []; + public function add(Tree $node) { + $this->nodes[] = $node; + + return $this; + } + + public function set($key, Tree $node) { + $this->nodes[$key] = $node; + + return $this; + } + public function getMaxDepth() : int { $depth = [0]; @@ -54,42 +66,44 @@ class Tree extends Graph return min($depth) + 1; } - public function postOrder() - { - - } - - public function preOrder() - { - - } - - public function levelOrder() - { - - } - - public function levelOrder2() - { - - } - - public function verticalOrder() + public function levelOrder(\Closure $callback) { + $depth = $this->getMaxDepth(); + for($i = 1; $i < $depth; $i++) { + $nodes = $this->getLevel($i); + callback($nodes); + } } public function isLeaf() : bool { - - } - - public function isSymmetric() : bool { - + return count($this->nodes) === 0; } public function getDimension() : int { - + $size = 1; + + foreach($this->nodes as $node) { + $size += $node->getDimension() + 1; + } + + return $size; + } + + public function getLevelNodes(int $level, array &$nodes) + { + --$level; + + foreach($this->nodes as $node) { + if($level === 0) { + $nodes[] = $this; + + return $nodes; + } else { + $this->getLevelNodes($level, $nodes); + } + } } } \ No newline at end of file