我不生产代码
我只是代码的搬运工

二叉树算法的PHP实现

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


本文章为本站原创,如转载请注明文章出处:https://www.sviping.com/archives/41

分享到:
上一篇: PHP实现RPC服务 下一篇: Docker容器,部署Nginx+PHP环境,php文件不执行返回404 Not Found
12