Nadesłany przez Marek Rynarzewski, 01 września 2012 17:42
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
bst.php:
<?php //Drzewo BST //Marek Rynarzewski //www.algorytm.org //wczytaj tablice //zapenij ze indeksy tablicy zaczynaja sie od 1 function fixArray(array &$a) { if (!is_numArr($a) or getFirstKey($a) != 1) { $a = setFirstKeyAs1($a); } } //zwraca true, jezeli wszystkie wartosc w tablicy sa liczbami function /*boolean*/ is_numArr(array $a) { foreach ($a as $k => $i) { if (!is_numeric($k)) return false; } return true; } //zwraca wartosc pierwszego klucza w tablicy (numer indeksu od ktorego zaczyna sie tablica) function /*mixed*/ getFirstKey(array $a) { foreach ($a as $k => $i) { return $k; } } //przerabia tablice tak, by pierwszy indeks by rowny 1 function /*array*/ setFirstKeyAs1(array $array) { $r = array(); foreach ($array as $k => $i) { if (getFirstKey($array) == $k) { $r[1] = $i; } else { $r[] = $i; } } return $r; } //Wezel drzewa BST class BSTNode { public function __construct($value) { $this->key = $value; } public $_parent = null; public $left = null; public $right = null; public $key = null; public function __toString() { return (($this->key != null)?((string)$this->key):('NULL')); } } //Drzewo BST class BST implements Countable { public $root; private $size = 0; //Tworzy drzewo BST na podstawie tablicy static /*BST*/ function toBST(array $a) { fixArray($a); $bst = new BST; $bst->root = new BSTNode($a[1]); for ($i = 2; $i <= count($a); $i ++) { $bst->insert(new BSTNode($a[$i])); } return $bst; } //Przechodz drzwo poprzecznie (in-order) public /*void*/ function inOrder(BSTNode $node = null) { if ($node != null) { $this->inOrder($node->left); echo $node; $this->inOrder($node->right); } } //Przechodz drzwo poprzecznie (in-order) i wywoluje podana funkcje dla kazdego wezla public /*mixed*/ function inOrderOwn($function, BSTNode $node = null) { if ($node != null) { $this->inOrderOwn($function, $node->left); $function($node); $this->inOrderOwn($function, $node->right); } } //Przechodz drzwo wzdluznie (pre-order) public /*void*/ function preOrder(BSTNode $node = null) { if ($node != null) { echo $node; $this->preOrder($node->left); $this->preOrder($node->right); } } //Przechodz drzwo wzdluznie (pre-order) i wywoluje podana funkcje dla kazdego wezla public /*mixed*/ function preOrderOwn($function, BSTNode $node = null) { if ($node != null) { $function($node); $this->preOrderOwn($function, $node->left); $this->preOrderOwn($function, $node->right); } } //Przechodz drzwo wstecznie (post-order) public /*void*/ function postOrder(BSTNode $node = null) { if ($node != null) { $this->postOrder($node->left); $this->postOrder($node->right); echo $node; } } //Przechodz drzwo wstecznie (post-order) i wywoluje podana funkcje dla kazdego wezla public /*void*/ function postOrderOwn($function, BSTNode $node = null) { if ($node != null) { $this->postOrderOwn($function, $node->left); $this->postOrderOwn($function, $node->right); $function($node); } } //Przeszukuje drzewo rekursywnie, w celu znalezienie podanej wartosci public function recursiveSearch($value, BSTNode $node = null) { echo 'value = '.$value.'<br/>node = '.$node.'<br/>'; if (($node == null) or ($node->key == $value)) { echo 'node == null or '.$node->key.' == '.$value.'<br/>'; return $node; } else { echo 'node != null or '.$node->key.' != '.$value.'<br/>'; if ($value < $node->key) { echo $value.' < '.$node->key.'<br/>'; return $this->recursiveSearch($value, $node->left); } else { echo $value.' >= '.$node->key.'<br/>'; return $this->recursiveSearch($value, $node->right); } } } //Przeszukuje drzewo iteracyjnie, w celu znalezienie podanej wartosci public function iterativeSearch($value, BSTNode $node = null) { while (($node != null) and ($value != $node->key)) { if ($value < $node->key) { $node = $node->left; } else { $node = $node->right; } } return $node; } //Zwraca warosc maksymalna w drzewie BST public function maximum(BSTNode $node = null) { while ($node->left != null) { $node = $node->left; } return $node; } //Zwraca warosc minimalna w drzewie BST public function minimum(BSTNode $node = null) { while ($node->right != null) { $node = $node->right; } return $node; } public function successor(BSTNode $node = null) { if ($node->right != null) { return $this->minimum($node); } $y = $node->_parent; while (($y != null) and ($node == $y->right)) { $node = $y; $y = $y->right; } return $y; } public function predecessor(BSTNode $node = null) { if ($node->left != null) { return $this->maximum($node); } $x = null; do { $x = $node; $y = $y->_parent; } while (($node != null) && ($node->right != $x)); return $y; } //Wstawia wartosc do drzewa BST public function insert(BSTNode $node = null) { $y = null; $x = $this->root; while ($x != null) { $y = $x; if ($node->key < $x->key) { $x = $x->left; } else { $x = $x->right; } } $node->_parent = $y; if ($y == null) { $this->root = $node; } else { if ($node->key < $y->key) { $y->left = $node; } else { $y->right = $node; } } $this->size++; } //Usuwa wartosc z drzewa BST public function delete(BSTNode $node = null) { if ($node->left == null) { $y = $node; } else { $y = $this->successor($node); } if ($y->left != null) { $x = $y->left; } else { $x = $y->right; } if ($x != null) { $x->_parent = $y->_parent; } if ($y->_parent == null) { $this->root = $x; } else { if ($y == $y->_parent->left) { $y->_parent->left = $x; } else { $y->_parent->right = $x; } } if ($y != $node) { $node->key = $y->key; } unset($node); $this->size--; } //Zwraca liczbe elementow w drzewie BST public function count() { return $this->size; } } ?>