由于平时经常需要用到对树的数据结构的操作,所以这里用PHP实现实现了对二叉树操作的常用算法,包括插入切点、先序遍历、中序遍历、后序遍历、删除节点等操作,代码如下:
/** * 树节点 */ class node { public $left; public $right; public $data; public function __construct($data) { $this->data = $data; } } class tree { protected $root; protected $nodeList = []; public static $prevTraverseOrder = 1; //先序遍历 public static $middleTraverseOrder = 2; //中序遍历 public static $afterTraverseOrder = 3; //后序遍历 /** * 添加节点 * @param mixed */ public function insert($data) { $this->insertNode($this->root, $data); } protected function insertNode($node, $data) { if (empty($node)) {//根节点 $this->root = new node($data); } elseif ($node->data >= $data) {//当前节点大于插入节点 if (empty($node->left)) { $node->left = new node($data); } else { $this->insertNode($node->left, $data); } } else {//当前节点小于插入节点 if (empty($node->right)) { $node->right = new node($data); } else { $this->insertNode($node->right, $data); } } } /** * 遍历二叉树 * @param int 遍历顺序 * @return array */ public function traverse($order) { $this->nodeList = []; $this->traverseOrder($this->root, $order); $nodeList = $this->nodeList; $this->nodeList = []; return $nodeList; } protected function traverseOrder($node, $order) { if (empty($node)) { return; } $order = intval($order); switch ($order) { case self::$prevTraverseOrder: $this->nodeList[] = $node->data; $this->traverseOrder($node->left, $order); $this->traverseOrder($node->right, $order); break; case self::$middleTraverseOrder: $this->traverseOrder($node->left, $order); $this->nodeList[] = $node->data; $this->traverseOrder($node->right, $order); break; case self::$afterTraverseOrder: $this->traverseOrder($node->left, $order); $this->traverseOrder($node->right, $order); $this->nodeList[] = $node->data; break; default: throw new Exception("error traverse order"); } } /** * 删除节点 */ public function delete($data) { return $this->deleteNode($this->root, $data); } protected function deleteNode($node, $data) { if (empty($node)) { return null; } if ($node->data > $data) { $node->left = $this->deleteNode($node->left, $data); } elseif ($node->data < $data) { $node->right = $this->deleteNode($node->right, $data); } else { if (empty($node->left) && empty($node->right)) { $node = null; } elseif (empty($node->left)) { $node = $node->right; } elseif (empty($node->right)) { $node = $node->left; } else { $max = $this->getMaxNode($node->left); if (is_null($max)) { throw new Exception("system error"); } $this->deleteNode($node, $max); $node->data = $max; } } return $node; } public function min() { return $this->getMinNode($this->root); } protected function getMinNode($node) { if (empty($node)) { return null; } return $node->left ? $this->getMaxNode($node->left) : $node->data; } public function max() { return $this->getMaxNode($this->root); } protected function getMaxNode($node) { if (empty($node)) { return null; } return $node->right ? $this->getMaxNode($node->right) : $node->data; } }
示例代码:
try { $nodes = [4, 11, 28, 33, 37, 17, 14, 16]; $tree = new tree(); foreach ($nodes as $node) { $tree->insert($node); } print_r($tree); $tree->delete(28); print_r($tree); } catch (Exception $e) { echo $e->getLine().PHP_EOL; echo $e->getFile().PHP_EOL; echo $e->getMessage().PHP_EOL; }