1.概念
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。
2.添加的思路
- 首先判断传入的结点是否为空
- 如果传入结点的值小于当前结点的值
2.1 如果当前结点的左子节点为空,直接将传入结点挂到当前结点的左子节点
2.2 否则就继续向当前结点的左子树递归 - 如果传入的结点值大于当前结点的值
3.1 如果当前结点的右子节点为空,直接将传入结点挂到当前结点的右子节点
3.2 否则就继续向当前结点的右子树递归
/**
* 递归的形式添加结点,满足二叉排序树的要求
* @param node
*/
public void add(Node node){
if(node == null){
return;
}
//判断传入的结点的值和当前子树的跟结点的值的关系
if(node.value < this.value){
//如果当前结点左子节点为空,直接挂上去
if(this.left == null){
this.left = node;
}else {
//递归的向左子树添加
this.left.add(node);
}
}else {
//添加的结点大于当前节点的值
if(this.right == null){
//如果右子树为空,直接挂上去
this.right = node;
}else {
//递归向右子树添加
this.right.add(node);
}
}
}
3.搜索
排序二叉树的搜索思路非常简单
- 首先判断需要搜索的值与当前结点的关系
- 如果小于当前结点则向该节点的左子节点遍历搜索
- 如果大于当前结点则向该节点的右子节点遍历搜索
- 注意空指针的判断和返回的条件
/**
* 结点的搜索
* @param value
* @return
*/
public Node searchNode(int value){
//判断是否相等
if(this.value == value){
return this;
}else if(this.value > value){
//如果大于传入值且左子树不为空,则向左递归
if(this.left != null) {
return this.left.searchNode(value);
}
}else if (this.value < value){
//如果小于传入值且右子树不为空,则向右递归
if(this.right != null) {
return this.right.searchNode(value);
}
}
return null;
}
4.遍历
在二叉排序树种遍历使用二叉树的中序遍历,这样可以按顺序打印出数据。
二叉排序树的最小值在左下角的叶子节点,最大值在右下角的叶子节点,正好符合中序遍历的特点
/**
* 中序遍历
*/
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}
System.out.println(this.value);
if(this.right != null){
this.right.infixOrder();
}
}
5删除
二叉树的删除有三种情况,需要分开讨论
5.1 删除叶子节点
叶子节点是没有子树的结点,那么删除叶子结点的思路如下
- 首先找到需要被删除的结点
- 再找到需要被删除的结点的父节点
- 确定删除结点实在父节点的左叶子节点还是右叶子结点
- 然后parent.left = null 或 parent.right = null
5.2 删除只有一颗子树的节点
- 首先找到需要被删除的结点
- 再找到需要被删除的结点的父节点
- 确定被删除节点的子节点是左子节点还是右子节点
- 判断被删除节点是父节点的左子节点还是右子节点
4.1 被删除节点是父节点的左子节点