二叉排序树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值,所以这么看来,二叉排序树是天然有序的,如果按照中序遍历,得到将是一个从小到大的有序数据集
删除节点
第一种情况是,如果要删除的节点没有子节点,我们只需要直接将父节点中,指向要删除节点的指针置为 null。
第二种情况是,如果要删除的节点只有一个子节点(只有左子节点或者右子节点),我们只需要更新父节点中,指向要删除节点的指针,让它指向要删除节点的子节点就可以了。
第三种情况是,如果要删除的节点有两个子节点,这就比较复杂了。我们需要找到这个节点的右子树中的最小节点,把它替换到要删除的节点上。然后再删除掉这个最小节点,因为最小节点肯定没有左子节点(如果有左子结点,那就不是最小节点了),然后,我们可以应用上面两条规则来删除这个最小节点(删除对象转移)
PHP
class TreeNode
{
public $value;
public $left;
public $right;
public function __construct($value)
{
$this->value = $value;
}
}
class Tree
{
public $root;
public function add($num)
{
$parent = $this->root;
if ($parent == null) {
$this->root = new TreeNode($num);
return true;
}
while ($parent) {
if ($num > $parent->value) {
if ($parent->right == null) {
$parent->right = new TreeNode($num);
return true;
}
$parent = $parent->right;
} elseif ($num < $parent->value) {
if ($parent->left == null) {
$parent->left = new TreeNode($num);
return true;
}
$parent = $parent->left;
} else {
return true;
}
}
}
public function find($num)
{
$parent = $this->root;
if ($parent == null) {
return false;
}
while ($parent) {
if ($parent->value == $num) {
return $parent;
}
if ($parent->value > $num) {
$parent = $parent->left;
}
if ($parent->value < $num) {
$parent = $parent->right;
}
}
return false;
}
public function delete($num)
{
$node = $this->root;
if ($node == null) {
return false;
}
$parent = null;
while ($node) {
if ($node->value == $num) {
break;
}
if ($node->value > $num) {
$parent = $node;
$node = $node->left;
}
if ($node->value < $num) {
$parent = $node;
$node = $node->right;
}
}
if ($parent == null) {
$this->root = null;
return true;
}
if ($node->left && $node->right) {
$min = $node->right;
$minParent = $node;
while ($min->left) {
$minParent = $min;
$min = $min->left;
}
$node->value = $min->value;
$node = $min;
$parent = $minParent;
}
if ($node->left) {
if ($parent->left->value == $node->value) {
$parent->left = $node->left;
} else {
$parent->right = $node->left;
}
} elseif ($node->right) {
if ($parent->left->value == $node->value) {
$parent->left = $node->right;
} else {
$parent->right = $node->right;
}
} else {
if ($parent->left->value == $node->value) {
$parent->left = null;
} else {
$parent->right = null;
}
}
}
}
//中序遍历
function midOrderTraverse($tree)
{
if ($tree == null) {
return;
}
midOrderTraverse($tree->left);
printf("%s\n", $tree->value);
midOrderTraverse($tree->right);
}
$tree = new Tree;
$tree->add(3);
$tree->add(3);
$tree->add(2);
$tree->add(5);
$tree->add(1);
$tree->add(4);
$tree->delete(1);
midOrderTraverse($tree->root);
var_dump($tree->find(3));
GO
package main
import (
"fmt"
)
type TreeNode struct {
value int
left *TreeNode
right *TreeNode
}
func main() {
tree := newTreeNode(3)
tree.add(3)
tree.add(2)
tree.add(5)
tree.add(1)
tree.add(4)
tree.del(1)
midOrderTraverse(tree)
fmt.Println(tree.find(3))
}
func newTreeNode(value int) *TreeNode {
return &TreeNode{
value: value,
left: nil,
right: nil,
}
}
func (node *TreeNode) add(num int) {
for {
if node == nil {
break
}
if node.value == num {
break
}
if num > node.value {
if node.right == nil {
node.right = newTreeNode(num)
break
}
node = node.right
}
if num < node.value {
if node.left == nil {
node.left = newTreeNode(num)
break
}
node = node.left
}
}
}
func (node *TreeNode) find(num int) *TreeNode {
for {
if node == nil {
return nil
}
if node.value == num {
return node
}
if num > node.value {
node = node.right
}
if num < node.value {
node = node.left
}
}
return nil
}
func (node *TreeNode) del(num int) {
var parent *TreeNode
for {
if node == nil {
break
}
if node.value == num {
break
}
if num > node.value {
parent = node
node = node.right
}
if num < node.value {
parent = node
node = node.left
}
}
if parent == nil {
return
}
if node.left != nil && node.right != nil {
min := node.right
minParent := node
for {
if min.left == nil {
break
}
minParent = min
min = min.left
}
node.value = min.value
node = min
parent = minParent
}
if node.left != nil {
if parent.left.value == node.value {
parent.left = node.left
} else {
parent.right = node.left
}
} else if node.right != nil {
if parent.left.value == node.value {
parent.left = node.right
} else {
parent.right = node.right
}
} else {
if parent.left.value == node.value {
parent.left = nil
} else {
parent.right = nil
}
}
}
func midOrderTraverse(node *TreeNode) {
if node == nil {
return
}
midOrderTraverse(node.left)
fmt.Println(node.value)
midOrderTraverse(node.right)
}