目录
1.概念
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
- 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
- 它的左右子树也分别为二叉搜索树
int a [] = {5,3,4,1,7,8,2,6,0,9};
2. 操作-查找 search
代码实现 :
public TreeNode search(int key){
TreeNode cur=root;
while (cur!=null){
if (cur.val<key){
cur=cur.right;
}else if (cur.val==key){
return cur;
}else {
cur=cur.left;
}
}
return null;
}
3.操作-插入 insert
-
如果树为空树,即根 == null,直接插入
-
如果树不是空树,按照查找逻辑确定插入位置,插入新节点
代码实现 :
public boolean insert(int val){
if (root==null){
root=new TreeNode(val);
return true;
}
TreeNode parent=null;
TreeNode cur=root;
while (cur!=null){
if (cur.val<val){
parent=cur;
cur=cur.right;
}else if (cur.val==val){
return false;//不能有相同的数据
}else {
parent=cur;
cur=cur.left;
}
}
TreeNode node=new TreeNode(val);
if (parent.val<val){
parent.right=node;
}else {
parent.left=node;
}
return true;
}
4. (难点)操作-删除 remove
删除remove操作比较复杂,需要画图分情况讨论 :
- 待删除结点为 cur, 待删除结点的双亲结点为 parent
4.1 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
4.2 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
4.3 cur.left != null && cur.right != null
- 需要在cur的左树当中 找最大值
- 或者在cur的右树当中 找最小值
- 使用替换法进行删除,用它的值填补到被删除节点中,再来处理该结点的删除问题
画图分析如下:
4. 需要删除cur如图为70,那我们就需要到右子树中找一个最小值75来与其替换(或者去左子树找最大值来与其替换)
5. 找到目标值75以后,再将其删除,如图所示(图为target==targetParent.left
情况
删除代码为: targetParent.left=target.right
- 如果为
target==targetParent.left
情况 :
删除代码为targetParent.right=target.right;
代码实现 :
public void remove(int key){
TreeNode cur=root;
TreeNode parent=null;
while (cur!=null){
if (cur.val==key){
//开始删除
removeNode(cur,parent);
break;
}else if (cur.val<key){
parent=cur;
cur=cur.right;
}else {
parent=cur;
cur=cur.left;
}
}
}
public 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){ //此时target为cur右树中最小的值
targetParent=target;
target=target.left;
}
cur.val=target.val;
if (target==targetParent.left){
targetParent.left=target.right;
}else {
targetParent.right=target.right;
}
}
}
5. 性能分析
- 最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:log2N(二叉树的高度)
- 最差情况下,二叉搜索树退化为单支树,其平均比较次数为:N/2(最好情况第一个就查找,最坏情况最后一个才查找到 平均下来就是 N/2)
附:整体基本二叉搜索树实现代码
class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val=val;
}
}
public class BinarySearchTree {
public TreeNode root=null;
public TreeNode search(int key){
TreeNode cur=root;
while (cur!=null){
if (cur.val<key){
cur=cur.right;
}else if (cur.val==key){
return cur;
}else {
cur=cur.left;
}
}
return null;
}
public boolean insert(int val){
if (root==null){
root=new TreeNode(val);
return true;
}
TreeNode parent=null;
TreeNode cur=root;
while (cur!=null){
if (cur.val<val){
parent=cur;
cur=cur.right;
}else if (cur.val==val){
return false;//不能有相同的数据
}else {
parent=cur;
cur=cur.left;
}
}
TreeNode node=new TreeNode(val);
if (parent.val<val){
parent.right=node;
}else {
parent.left=node;
}
return true;
}
public void remove(int key){
TreeNode cur=root;
TreeNode parent=null;
while (cur!=null){
if (cur.val==key){
//开始删除
removeNode(cur,parent);
break;
}else if (cur.val<key){
parent=cur;
cur=cur.right;
}else {
parent=cur;
cur=cur.left;
}
}
}
public 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){ //此时target为cur右树中最小的值
targetParent=target;
target=target.left;
}
cur.val=target.val;
if (target==targetParent.left){
targetParent.left=target.right;
}else {
targetParent.right=target.right;
}
}
}
//中序遍历
public void inOrder(TreeNode root){
if (root==null){
return;
}
inOrder(root.left);
System.out.print(root.val+" ");
inOrder(root.right);
}
public static void main(String[] args) {
//测试:
int[] array = {10,8,19,3,9,4,7};
BinarySearchTree binarySearchTree = new BinarySearchTree();
for (int i = 0; i < array.length; i++) {
binarySearchTree.insert(array[i]);
}
binarySearchTree.inOrder(binarySearchTree.root);
System.out.println("插入重复的数据");
System.out.println(binarySearchTree.insert(3));
System.out.println("删除数据:");
binarySearchTree.remove(7);
System.out.println();
binarySearchTree.inOrder(binarySearchTree.root);
}
}
-
7被成功删除,测试成功 !
-
over ~