什么是二叉搜索树?
二叉搜索树又称二叉排序数(它可能也是棵空树),简单的来说 根节点左边 比根节点小,根节点右边比根节点大。
话不多说 上个图 便于理解
具有的性质
二叉搜索树操作代码实现
1.查找(查找key是否在二叉搜索树中)
代码实现
//二叉搜索树 class Node { public int val; public Node left; public Node right; public Node(int val) { this.val = val; } } public class BinarySearchTree { public Node root = null;//根节点 //查找key在不在二叉搜索树中 public Node search(int key) { Node cur = root; //这里分三种情况 while (cur != null) { //1.如果cur的值刚好等于key if(cur.val == key) { return cur; //2.如果cur.val 小于 key //那么要查找的key 在 其右子树 }else if(cur.val < key) { cur = cur .right; //3.如果cur.val 大于 key //那么要查找的 key 在 其左子树 }else { cur = cur.left; } } return null;//代表没有这个数据 }
2.插入(对于二叉搜素数来说,插入的数据一定是叶子节点)//这一点很重要,知道了就很好写
代码实现
//二叉搜索树插入一个key //对于二叉搜索树来说 插入的数据一定是 叶子节点 public boolean insert(int val) {
//如果是空数 直接插入 if(root == null) { root = new Node(val);//root等于新插入的节点,节点的值为val return true; } //如果不是 空数 那么 接下来我们去找叶子节点 Node cur = root;//一样的 用cur代替root Node parent = null;//用一个双亲节点 while (cur != null) { //1,如果val的值大于cur 那么val 在cur的右子树 if(cur.val < val) { parent = cur; cur = cur.right; //2.如果val的值刚好等于cur的值 不能插入 }else if(cur.val == val) { return false;//不能有相同的数据进行插入 //3.如果val的值小于cur 那么val 在cur的左子树 }else { parent = cur; cur = cur.left; } } //找到叶子节点以后我们要去比较parent.val 和val的大小再进行插入 Node node = new Node(val);//新节点val if(parent.val < val) { parent.right = node;//这里根据二叉搜索树的性质,parent为根节点 //val比根节点大所以在根节点右边 }else { parent.left = node; } return true; }
3.删除(难点)
1.当cur.left == null的时候
2.当cur.right == null 的时候
3.当cur.left != null && cur.right != null 的时候
需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题
用tap代替cur cur.right = ta 如果 ta.left == null 了 交换 ta和 cur的值
这里 是 ta 在tap 左边的情况
这里是 ta 在tap 右边的情况
//二叉搜素数 删除操作(难点) public void remove(int key) { Node cur = root; Node 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(Node cur,Node parent) { //第一种情况 cur.left == null if (cur.left == null) { //1.cur是root 则 root = cur.right if (cur == root) { root = cur.right; //2.cur不是root cur是parent.left } else if (cur == parent.left) { parent.left = cur.right; //3,cur不是root cur是parent.right } else { parent.right = cur.right; } //第二种情况 cur.right == null } else if (cur.right == null) { //1,cur是root root = cur.left if (cur == root) { root = cur.left; //2.cur不是root cur是parent.left } else if (cur == parent.left) { parent.left = cur.left; //3,cur不是root cur是parent.right } else { parent.right = cur.left; } //第三种情况 cur.left!=null && cur.right!=null(难点) //1.cur的左树当中找最大值2.cur的右树当中找最小值 //核心就是替换 } else { Node targetParent = cur; Node targer = cur.right; //左树找不等于空的时候 while (targer.left != null) { targetParent = targer; targer = targer.left; } cur.val = targer.val;//交换值 //这里需要判断 ta 是在 tap的左边还是右边 if (targer == targetParent.left) { targetParent.left = targer.right; } else { targetParent.right = targer.right; } } } }