由于平时经常需要用到对树的数据结构的操作,所以这里用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;
}