二叉搜索树:
又称二叉排序树,它或者是一棵空树**,或者是具有以下性质的二叉树:
1.若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
2.若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
3.它的左右子树也分别为二叉搜索树
搜索二叉树的操作主要有:
a) 增加
b) 查找
c) 删除
(PS:为什么没有修改? 因为修改会破坏搜索二叉树的结构,一般都是先删除再插入,或者不修改key的值,只修改value)
代码实现
结点
public static class TreeNode{
public int key;
public int value;
TreeNode left;
TreeNode right;
public TreeNode(int key, int value) {
this.key = key;
this.value = value;
}
}
增加:
private static TreeNode root;
public static boolean put(int key,int value){
TreeNode NewNode=new TreeNode(key,value);
if(root == null){
root=NewNode;
return true;
}
TreeNode cur=root;
TreeNode prev=null;
while(cur !=null){
if(key>cur.key){
prev=cur;
cur=cur.right;
}else if(key < cur.key){
prev=cur;
cur=cur.left;
}else{
return false;
}
}
if(key >prev.key){
prev.right=NewNode;
}else {
prev.left=NewNode;
}
return true;
}
查找:
public static TreeNode Find(int key,int value){
TreeNode cur=root;
while(cur != null){
if(key>cur.key){
cur=cur.right;
} else if(key <cur.key){
cur=cur.left;
}else {
return cur;
}
}
return null;
}
删除:
public static boolean remove(int key,int value){
TreeNode cur=root;
TreeNode prev=null;
while(cur!=null){
if(key>cur.key){
prev=cur;
cur=cur.right;
}else if(key <cur.key){
prev=cur;
cur=cur.left;
}else{
removeHelp(prev,cur);
return true;
}
}
return false;
}
public static void removeHelp(TreeNode prev,TreeNode cur){
if(cur.left == null){
if(cur==root){
root=root.right;
}else if(prev.left==cur){
prev.left=cur.right;
}else {
prev.right=cur.right;
}
} else if (cur.right == null){
if(cur == root){
root=root.left;
}else if(cur==prev.left){
prev.left=cur.left;
}else{
prev.right=cur.left;
}
}else{
TreeNode goatParents = cur;
TreeNode scapegoat = cur.right;
while(scapegoat.left != null){
goatParents=scapegoat;
scapegoat=scapegoat.left;
}
cur.key=scapegoat.key;
cur.value=scapegoat.value;
if(scapegoat == goatParents.left){
goatParents.left=scapegoat.left;
} else {
goatParents.right=goatParents.right;
}
}
}
这里删除需要考虑很多种情况(cur是要删除的结点,parent是cur的父亲结点):
一. cur.left == null
- cur 是 root,则 root = cur.right
- cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
- cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
二. cur.right == null - cur 是 root,则 root = cur.left
- cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
- cur 不是 root,cur 是 parent.right,则 parent.right = cur.left
三. cur.left != null && cur.right != null - 需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被
删除节点中,再来处理该结点的删除问题
须知:
二叉搜索树的中序遍历是有序的。