提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一、概念
1、二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
另外,它的左右子树也分别为二叉搜索树
二、相关操作
1、查找
/**
* 最好情况:完全二叉树O(logN)
* 最坏情况:单分支树O(N)
* @param key
* @return
*/
public boolean search(int key){
TreeNode cur = root;
while (cur.val != key){
if (cur.val >key){
cur = cur.right;
}else if (cur.val < key){
cur = cur.left;
}else {
return true;
}
}
return false;
}
2、插入
/**
* 插入
* @param val
* @return
*/
public boolean insert(int val){
if (root == null){
root = new TreeNode(val);
return true;
}
TreeNode cur = root;
TreeNode parent = null;
while (cur != null){
if (cur.val < val) {
parent = cur;
cur = cur.right;
} else if (cur.val > val) {
parent = cur;
cur = cur.left;
}else { //二维搜索树中不能有相同的数字元素
return false;
}
}
TreeNode node = new TreeNode(val);
if (parent.val < val){
parent.right = node;
}else {
parent.left = node;
}
return true;
}
3、 删除(重点)
设待删除结点为 cur, 待删除结点的双亲结点为 parent
1. 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
2. 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
3、cur.left != null && cur.right != null
需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题
删除操作总代码`
public void remove(int key){
TreeNode cur = root;
TreeNode parent = null;
while (cur != null){
if (cur.val < key){
parent = cur;
cur = cur.right;
} else if (cur.val > key) {
parent = cur;
cur = cur.left;
}else {
removeNode(cur,parent);
}
}
}
//设待删除结点为 cur, 待删除结点的双亲结点为 parent
private void removeNode(TreeNode cur, TreeNode parent) {
if (cur.left == null){
if (cur == root){
root = cur.right;
} else if (cur == parent.left) {
parent.left = cur.right;
}else {
parent.right = cur.right;
}
} else if (cur.right == null) {
if (cur == root){
root = cur.left;
}else if (cur == parent.left){
parent.left = cur.left;
}else {
parent.right = cur.left;
}
}else {
TreeNode targetParent = cur;
TreeNode target = cur.right;
while (target.left != null){
targetParent = target;
target = targetParent.left;
}
cur.val = target.val;
//删除target
if (targetParent.left == target) {
targetParent.left = target.right;
}else {
targetParent.right =target.right;
}
}
}