/** * @param Node $node * @return ListNode */ protected function convertNode(Node $node) { if ($node instanceof ListNode) { return $node; } $listNode = new ListNode($node->getId(), $node->getX(), $node->getY(), 0); $listNode->setData($node->getData()); return $listNode; }
public static function sum(Node $n1, Node $n2) { $head = $tail = null; $carry = 0; while ($n1 !== null || $n2 !== null) { $sum = $carry; if ($n1 !== null) { $sum += $n1->getData(); $n1 = $n1->getNext(); } if ($n2 !== null) { $sum += $n2->getData(); $n2 = $n2->getNext(); } if ($sum >= 10) { $digit = $sum % 10; $node = new Node($digit); if ($head === null) { $head = $tail = $node; } else { $tail->setNext($node); $tail = $node; } $carry = ($sum - $digit) / 10; } else { $node = new Node($sum); if ($head === null) { $head = $tail = $node; } else { $tail->setNext($node); $tail = $node; } $carry = 0; } } if ($carry > 0) { $node = new Node($carry); if ($head === null) { $head = $tail = $node; } else { $tail->setNext($node); $tail = $node; } } return $head; }
public static function partition(Node $node, $x) { $head = $node; $previousNode = null; while ($node !== null) { if ($node->getData() < $x && $previousNode !== null) { // remove the node from this part of the list $previousNode->setNext($node->getNext()); // put this node at the begining of the list $node->setNext($head); // reset head $head = $node; // reset node for the next iteration $node = $previousNode; } else { $previousNode = $node; $node = $node->getNext(); } } return $head; }
/** * Merges this node with another node. * Copies all keys of $mergeNode into this node. * Puts $middleBlock between them, using the last-reference of this as reference. * Adopts the last-reference of $mergeNode. * * This does not sort the keys! * $mergeNode's first key must be higher then this-node's last key. * Always merge the node with bigger values into the one with smaller values, * never the other way around. * * @param Node $mergeNode * @param array $middleBlock * @throws \ErrorException */ public function merge(Node $mergeNode, array $middleBlock = null) { if ($mergeNode->getKeyLength() !== $this->keyLength) { throw new ErrorException("Tried to merge nodes with different key-length!"); } if (!is_null($middleBlock) && count($middleBlock) < 3) { $dump = str_replace("\n", "", var_export($middleBlock, true)); throw new ErrorException("Invalid middle-block given for merge! ({$dump})"); } $myLastIndex = $this->getLastWrittenIndex(); $mergeLastIndex = $mergeNode->getLastWrittenIndex(); if ($myLastIndex + $mergeLastIndex + 2 > $this->forkRate - 1) { $actual = $myLastIndex + $mergeLastIndex + 2; $expect = $this->forkRate - 1; throw new ErrorException("Cannot merge nodes because theyre sum is too big! ({$actual} > {$expect})"); } if ((trim($this->getLastReference(), "") === '') !== (trim($mergeNode->getLastReference(), "") === '')) { throw new ErrorException("Cannot merge leaf-node and non-leaf-node!"); } $mergeData = $mergeNode->getData(); $newData = substr($this->data, 0, ($myLastIndex + 1) * $this->keyLength * 3); if (!is_null($middleBlock)) { $newData .= $this->getLastReference() . $middleBlock[1] . $middleBlock[2]; } $newData .= substr($mergeData, 0, ($mergeLastIndex + 1) * $this->keyLength * 3); $newData = str_pad($newData, $this->forkRate * $this->keyLength * 3, "", STR_PAD_RIGHT); $newData .= substr($mergeData, strlen($mergeData) - $this->keyLength); $this->setData($newData); }
/** * @param Node $node * @return $this * @throws \Exception */ public function removeNode($node) { // For reorder old node branch $dataReorderOld = [$this->_orderField => new \Zend_Db_Expr($this->_conn->quoteIdentifier($this->_orderField) . '-1')]; $conditionReorderOld = $this->_conn->quoteIdentifier($this->_parentField) . '=' . $node->getData($this->_parentField) . ' AND ' . $this->_conn->quoteIdentifier($this->_orderField) . '>' . $node->getData($this->_orderField); $this->_conn->beginTransaction(); try { $condition = $this->_conn->quoteInto("{$this->_idField}=?", $node->getId()); $this->_conn->delete($this->_table, $condition); // Update old node branch $this->_conn->update($this->_table, $dataReorderOld, $conditionReorderOld); $this->_conn->commit(); } catch (\Exception $e) { $this->_conn->rollBack(); throw new \Exception('Can\'t remove tree node'); } parent::removeNode($node); return $this; }
private function printPathsRec(Node $node = NULL, $path = array(), $pathLen = 0) { if ($node === NULL) { return; } else { $this->pathLen++; $this->path[$this->pathLen] = $node->getData(); } }