什么是二叉搜索树
二叉搜索树又称二叉排序树,它或者是一棵空树**,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
删除的八种范例
这里删除需要分很多情况,这里我们把要删除的节点设为cur,它的父节点为parent
cur.left == null
1. cur 是 root,则 root = cur.right
2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
cur.right == null
1. cur 是 root,则 root = cur.left
2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.left
cur.left != null && cur.right != null
需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题
1.找到的节点有向左走的情况(1.2)
2.找到的节点没有向左走的情况,一路右下(1.3)
public void remove(int key){
BinaryNode cur = root;
BinaryNode parent = null;
//先找到要删除的节点的位置
while(cur != null){
if(key < cur.key){
parent = cur;
cur = cur.left;
}else if(key > cur.key){
parent = cur;
cur = cur.right;
}else{
removeNode(parent,cur);
return;
}
}
}
private void removeNode(BinaryNode parent, BinaryNode cur) {
if(cur.left == null){
//1
if(cur == root){
root = cur.right;
}
//2
else if(cur == parent.left){
parent.left = cur.right;
}
//3
else if(cur == parent.right){
parent.right = cur.right;
}
}
else if(cur.right == null){
//4
if(cur == root){
root = cur.left;
}
//5
else if(cur == parent.left){
parent.left = cur.left;
}
//6
else if(cur == parent.right){
parent.right = cur.left;
}
}
else{
//在右子树中找到最小值,来替换这个节点,
// 顺便删掉找到的最小值的那个节点
BinaryNode goat = cur.right;
BinaryNode goatParent = cur;
while(goat.left !=null){
goatParent =goat;
goat =goat.left;
}
cur.key = goat.key;
cur.value = goat.value;
//7
if(goat == goatParent.left){
goatParent.left = goat.right;
}else{ //8
goatParent.right = goat.right;
}
}
}
添加
从root出发,进行查找动作,直到cur为空的时候,此时就把新节点插入到cur所在的位置就好了,为了完成这个插入,还需要记录cur的父节点的位置
//插入
public void put(int key,int value){
if(root == null){
root = new BinaryNode(key,value);
return;
}
//不为空时,从根节点出发,找到合适的插入位置,
//这里插入的位置肯定是一个空的,那么就需要一个父节点,
// 来指向插入位置的父节点,进行插入
BinaryNode cur = root;
BinaryNode parent = null;
while(cur !=null){
if(key < cur.key){
parent = cur;
cur = cur.left;
}else if(key > cur.key){
parent = cur;
cur = cur.right;
}else{
cur.value = value;
return;
}
}
//没有相同节点,这里直接到插入位置
BinaryNode newN = new BinaryNode(key,value);
if(newN.key < parent.key){
parent.left = newN;
}else{
parent.right = newN;
}
}
获取任意节点
public Integer get(int key){
BinaryNode cur = root;
while(cur != null){
if(key < cur.key){
cur = cur.left;
}else if(key > cur.key){
cur = cur.right;
}else{
return cur.value;
}
}
return null;
}
测试代码
public class Test {
public static void main(String[] args) {
BinSeTree binSeTree = new BinSeTree();
binSeTree.put(3,3);
binSeTree.InOderTraversal();
binSeTree.put(2,2);
binSeTree.put(1,1);
binSeTree.InOderTraversal();
System.out.println(binSeTree.get(2));
binSeTree.put(4,4);
binSeTree.remove(3);
binSeTree.InOderTraversal();
}
}