二叉排序树之PHP代码简释

写在前面:本文侧重诠释对算法的思考记录过程,忽略其他诸如代码简洁、字符编码等细节问题。

<?php
class Node {
	public $data;
	public $left = NULL;
	public $right = NULL;

	public function __construct($data) {
		$this->data = $data;
	}	
}

//二叉排序树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,
//而右子树节点的值都大于这个节点的值。
//构造二叉排序树的目的,并不是为了排序,而是为了提高查找、插入和删除的速度。
//不论是插入、删除、还是查找,二叉排序树的时间复杂度都等于二叉树的高度,
//最好的情况当然是满二叉树或完全二叉树,时间复杂度是 O(logn),性能相当好
//最差的情况是二叉排序树退化为线性表(斜树),此时的时间复杂度是 O(n)
class BinarySortedTree {
	private static $tree;

	public function getTree() {
		return self::$tree;
	}

	//插入节点
	public function insert($data) {
		//如果是空树,就插入到根节点
		if (!self::$tree) {
			self::$tree = new Node($data);
			return;
		}

		$p = self::$tree;
		while ($p) {
			if ($data < $p->data) {
				if (!$p->left) {
					$p->left = new Node($data);
					return;
				}
				$p = $p->left;
			} elseif ($data > $p->data) {
				if (!$p->right) {
					$p->right = new Node($data);
					return;
					
				}
				$p = $p->right;
			}
		}		

	}

	//前序遍历
	public function preOrderTraverse($p) {
		if (!$p) {
			return;
		}
		if (!empty($p->data)) {
			printf("%s\n", $p->data);
			$this->preOrderTraverse($p->left);
			$this->preOrderTraverse($p->right);
		}		
	}

	//中序遍历
	public function midOrderTraverse($p) {
		if (!$p) {
			return;
		}
		if (!empty($p->left)) {
			$this->midOrderTraverse($p->left);
			printf("%s\n", $p->data);
			// var_dump($p);	
			$this->midOrderTraverse($p->right);
		}		
	}

	//后序遍历
	public function afterOrderTraverse($p) {
		if (!$p) {
			return;
		}
		if (!empty($p->left)) {
			$this->afterOrderTraverse($p->left);
			$this->afterOrderTraverse($p->right);
			printf("%s\n", $p->data);
		}	
	}

	//查找节点数据
	public function select($data) {
		if (!self::$tree) {
			return;
		}

		$p = self::$tree;
		while($p) {
			if ($data < $p->data) {
				$p = $p->left;
			} elseif ($data > $p->data) {
				$p = $p->right;			
			} else {
				return $p;
			}
		}
		return NULL;
	}

	//删除数据节点
	public function delete($data) {
		if (!self::$tree) {
			return;
		}

		$p = self::$tree;
		$pParent = NULL;
		while($p && $p->data != $data) {
			$pParent = $p;
			if ($data < $p->data) {
				$p = $p->left;
			} else {
				$p = $p->right;
			}
		}

		if (!$p) {
			return NULL;
		}

		if ($p->left && $p->right) {
			$lastLeft = $p->right; //右子树的最小节点
			$lastLeftParent = $p;
			while ($lastLeft->left) {
				$lastLeftParent = $lastLeft;
				$lastLeft = $lastLeft->left;
			}
			$p->data = $lastLeft->data;
			$p = $lastLeft;
			$pParent = $lastLeftParent;
		}

		$child = NULL;
		if ($p->left) {
			$child = $p->left;
		} elseif($p->right) {
			$child = $p->right;
		}

		if (!$pParent) {
			self::$tree = $child; //删除的是根节点
		} elseif($pParent->left == $p) {
			$pParent->left = $child;
		} elseif($pParent->right == $p) {
			$pParent->right = $child;
		}
	}
}


$treeObj = new BinarySortedTree();
$treeObj->insert(33);
$treeObj->insert(16);
$treeObj->insert(50);
$treeObj->insert(13);
$treeObj->insert(18);
$treeObj->insert(34);
$treeObj->insert(58);
$treeObj->insert(15);
$treeObj->insert(17);
$treeObj->insert(25);
$treeObj->insert(51);
$treeObj->insert(66);
$treeObj->insert(19);
$treeObj->insert(27);
$treeObj->insert(55);

$tree = $treeObj->getTree();

$treeObj->midOrderTraverse($tree);
// echo "<hr/>";

// $treeObj->delete(13);
// $treeObj->delete(18);
// $treeObj->delete(55);

// // $treeObj->preOrderTraverse($tree);//33 16 13 15 18 17 25 19 27 50 34 58 51 55 66
// // echo "<hr/>";
// $treeObj->midOrderTraverse($tree);//16 13 15 18 17 25 19 27 33 50 34 58 51 55 66
// // echo "<hr/>";
// // $treeObj->afterOrderTraverse($tree);//16 13 15 18 17 25 19 27 50 34 58 51 55 66 33
// // echo "<hr/>";

参考来源:https://xueyuanjun.com/books/data-structure-and-algorithms

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值