二叉排序树
思路:
- 二叉排序树的添加
1.1 将第一个添加的作为根节点了
1.2 比当前遍历的节点小的 添加到 左边
1.3 比当前遍历的节点大的 添加到 右边
1.4 尽量不添加相同值得到二叉排序树中,可以在添加的时候 if else 到默认右边- 二叉排序树的遍历
2.1 中序遍历 : 从小到大- 二叉排序树的删除
3.1 删除分三种情况; 1. 删除叶子节点(没有左右子节点)2. 删除带有一个子节点的 3. 删除带有两个子节点的
3.2 准备
3.2.1 查找需要被删除的节点的方法
3.2.2 查找需要被删除的节点的父节点的方法 【重点】
3.2.3 查找删除节点的右子树最小的节点。或者查找左子树最大节点。之后删除该最小节点(叶子节点)【删除带有两个子节点时用到】
3.3 如果找到了待删除的节点, 额外判断删除是不是根节点。
public class BinarySortTreeDemo {
public static void main(String[] args) {
// 数组
int[] arr = {7,3,10,12,5,1,9,2};
BinarySortTree bs = new BinarySortTree();
for (int d : arr){
bsNode n = new bsNode(d);
bs.add(n);
}
bs.infixOrder();
System.out.println("========分割线============");
bs.delNode(new bsNode(2));
bs.delNode(new bsNode(5));
bs.delNode(new bsNode(9));
bs.delNode(new bsNode(12));
bs.delNode(new bsNode(7));
bs.delNode(new bsNode(3));
bs.delNode(new bsNode(10));
bs.delNode(new bsNode(1));
// bs.delNode(new bsNode(2));
// bs.delNode(new bsNode(5));
// bs.delNode(new bsNode(9));
// bs.delNode(new bsNode(12));
// bs.delNode(new bsNode(1));
// bs.delNode(new bsNode(3));
// bs.delNode(new bsNode(7));
// bs.delNode(new bsNode(10));
bs.infixOrder();
}
}
class BinarySortTree{
public bsNode root ;
/**
* 添加节点
*/
public void add(bsNode node){
if(root == null){
// 如果根节点为 空
root = node;
}else {
root.add(node);
}
}
/**
* 中序遍历
*/
public void infixOrder(){
if(root == null){
System.out.println("二叉排序树为空");
return ;
}
root.infixOrder();
}
/**
* 删除具有左右子节点的节点时
* -找出右子树最小的节点
* @return
*/
public bsNode getMinInRight(bsNode node){
// 为空
if(node == null){
return null;
}
// 跑去删除节点的右子树呗
bsNode rightNode = node.right; // 起始位置
// 然后一直向左找最小,找到叶子节点
while (rightNode.left != null){
rightNode = rightNode.left;
}
// 删除右子树最小节点
delNode(rightNode);
return rightNode;
}
/**
* 删除节点
*/
public void delNode(bsNode node){
// 为空
if(node == null){
return ;
}
// 删除
bsNode targetNode = root.searchNode(node);
if(targetNode == null){
System.out.println("没有找到删除的节点");
return ;
}
if(root.left == null && root.right == null){
root = null;
return ;
}
// 找父节点
bsNode parent = root.nodeParent(node);
// 找到了删除的节点、找到了删除节点的父节点
// 删除情况
if(targetNode.left == null && targetNode.right == null){
// 删除的是叶子节点
if(parent.left == targetNode){
parent.left = null;
}else if(parent.right == targetNode){
parent.right = null;
}
}else if(targetNode.left != null && targetNode.right != null){
// 删除具有左右子节点的节点
bsNode minInRight = getMinInRight(targetNode); // 这里得到了最小的节点。
// 直接替换掉值就可以了
// 其他关系保持
targetNode.value = minInRight.value;
}else {
// 删除具有左右其中一个子节点的节点
if(targetNode.left != null ){
// 这里之前有漏洞,补上
if(parent != null){
if(parent.left.value == node.value){
parent.left = targetNode.left;
} else {
parent.right = targetNode.left;
}
} else {
root = targetNode.left;
}
}else {
// 删除只有右子节点的节点
if(parent != null){
// 删除根节点的时候, parent 为 null,所以这里还是需要判断一下
if(parent.right.value == node.value){
parent.right = targetNode.right;
} else {
parent.left = targetNode.right;
}
} else {
root = targetNode.right;
}
}
}
}
}
/**
* 节点
*/
class bsNode{
public int value;
public bsNode left;
public bsNode right;
public bsNode(int value) {
this.value = value;
}
@Override
public String toString() {
return "bsNode{" +
"value=" + value +
'}';
}
/**
* 添加节点
* @param node
*/
public void add(bsNode node){
// 递归
if(this.value > node.value){
if(this.left == null){
this.left = node;
return ;
}
this.left.add(node);
} else if(this.value < node.value){
if(this.right == null){
this.right = node;
return ;
}
this.right.add(node);
}
}
/**
* 中序遍历
*/
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}
System.out.println(this);
if(this.right != null){
this.right.infixOrder();
}
}
/**
* 查找需要删除的节点
*/
public bsNode searchNode(bsNode node){
// 为空
if(node == null){
return null;
}
if(this.value == node.value){
return this;
}else if(this.value < node.value){
// 大于当前节点的值
// 跑去右边呗
if(this.right == null){ return null; }
return this.right.searchNode(node);
}else {
// 小于当前节点的值
// 跑去左边呗
if(this.left == null){ return null; }
return this.left.searchNode(node);
}
}
/**
* 找到需要呗删除的节点的父节点
* @param node 需要呗删除的节点
* @return
*/
public bsNode nodeParent(bsNode node){
// 为空
if(node == null ){
return null;
}
// 比较
if(this.left != null && this.left.value == node.value){
return this;
}else if(this.right != null && this.right.value == node.value){
return this;
}else if( this.left != null && this.value > node.value){
// 如果当前值小于左子节点
// 跑左边呗
return this.left.nodeParent(node);
}else if(this.right != null && this.value <= node.value){
return this.right.nodeParent(node);
}else {
// 都不满足
// 根节点
// 没有父节点
return null;
}
}
}