Пример #1
0
 /**
  * @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;
 }
Пример #4
0
 /**
  * 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);
 }
Пример #5
0
 /**
  * @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;
 }
Пример #6
0
 private function printPathsRec(Node $node = NULL, $path = array(), $pathLen = 0)
 {
     if ($node === NULL) {
         return;
     } else {
         $this->pathLen++;
         $this->path[$this->pathLen] = $node->getData();
     }
 }