1、TreeSet和TreeMap插入元素时一定要比较大小,因为其底层是红黑树(由二叉搜索树调整形成)。
2、删除二叉搜索树的目标节点时有三种情况:
(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
(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
(3)cur.left != null && cur.right != null
这里是在cur节点(要删除的目标节点)的右边找替罪羊,在cur的右子树中找到最左边的节点
①target==targetParent.left,则targetParent.left=target.right
②target==targetParent.right,则targetParent.right=target.right
public class BinarySearchTree {
static class TreeNode {
public int key;
public TreeNode left;
public TreeNode right;
TreeNode(int key) {
this.key = key;
}
}
public TreeNode root;
//插入一个元素,二叉搜索树不能插入多个相同的数据,插入时是在叶子节点的left和right处插入,每插入一个元素要与之前的元素进行比较
public boolean insert(int key) {
TreeNode cur = root;
TreeNode parent = null;
TreeNode node = new TreeNode(key);
if(cur == null) {
cur = node;
return true;
}
while(cur != null) {
if(cur.key > key) {
parent = cur;
cur = cur.left;
}else if(cur.key < key) {
parent = cur;
cur = cur.right;
}else {
break;
}
}
if(parent.key > key) {
parent.left = node;
}else {
parent.right = node;
}
return true;
}
//查找key是否存在
public TreeNode search(int key) {
TreeNode cur = root;
while(cur != null) {
if(cur.key > key) {
cur = cur.left;
}else if(cur.key < key) {
cur = cur.right;
}else {
return cur;
}
}
return null;//这里已经包含了root==null和找不到两种情况
}
//删除key的值
public boolean remove(int key) {
TreeNode cur = root;
TreeNode parent = null;
while(cur != null) {
if(cur.key > key) {
parent = cur;
cur = cur.left;
}else if(cur.key < key) {
parent = cur;
cur = cur.right;
}else {
removeNode(parent, cur);
return true;
}
}
return false;
}
private void removeNode(TreeNode parent, TreeNode cur) {
if(cur.left == null) {//包括left为空right不为空,left为空right也为空两种情况
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) {//包括right为空left不为空,right为空left也为空两种情况
if(cur == root) {
root = cur.left;
}else if(cur == parent.left) {
parent.left = cur.left;
}else {
parent.right = cur.left;
}
}else {//left和right都不为空,这里是在cur节点(要删除的目标节点)的右边找替罪羊,在cur的右子树中找到最左边的节点
TreeNode targetParent = cur;
TreeNode target = cur.right;
while(target.left != null) {
targetParent = target;
target = target.left;
}
cur.key = target.key;
if(target == targetParent.left) {
targetParent.left = target.right;
}else {
targetParent.right = target.right;
}
}
}
}