目录
1.搜索树
1.1概念
二叉搜索树又称二叉排序树,它或者是一棵空树,或者具有以下性质:
1> 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
2> 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
3> 它的左右子树也分别为二叉搜索树
1.2查找
java
public class BinarySearchTree {
static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
public TreeNode root;//根结点
public TreeNode search(int val) {
TreeNode cur = root;
while (cur != null) {
if (cur.val < val) {
cur = cur.right;
} else if (cur.val > val) {
cur = cur.left;
} else {
return cur;
}
}
return null;
}
}
1.3插入
从根节点开始,比根结点小向左走,比根结点大向右走,直到达到叶子结点,插入该叶子结点。
java
public boolean insert(int key) {
TreeNode node = new TreeNode(key);
//第一次插入
if (root == null) {
root = node;
return true;
}
//之后的插入
TreeNode cur = root;
TreeNode parent = null;//用来记录cur的位置
while (cur != null) {
if (cur.val < key) {
parent = cur;
cur = cur.right;
} else if (cur.val > key) {
parent = cur;
cur = cur.left;
}else { //相同数据不能插入
return false;
}
}
if (parent.val > key) {
parent.left = node;
}else {
parent.right = node;
}
return true;
}
1.4删除
方法:替罪羊删除法
找到左树的最右边,即左树最大值,或找到右树的最左边,即右树的最小值 作为替罪羊。
java
/**
* @param cur 要删除的结点
* @param parent 要删除节点的父节点
*/
private void remove(TreeNode cur, TreeNode parent) {
if(cur.left == null) { //1.cur的左树为空
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) { //2.cur的右树为空
if(cur == root) {
root = cur.left;
}else if(cur == parent.left) {
parent.left = cur.left;
}else {
parent.right = cur.left;
}
}else { //3.cur的左右树都不为空
//方法:替罪羊删除法
//找右树的最小值,即右树的最左边作为替罪羊
TreeNode targetParent = cur;
TreeNode target = cur.right;
while (target.left != null) { //直到左树为空,说明已经找到了替罪羊
targetParent = target;
target = target.left;
}
cur.val = target.val; //覆盖
//回到了上面的情况1和情况2
if(target == targetParent.left) {
targetParent.left = target.right;
}else {
targetParent.right = target.right;
}
}
}
Set中存储key,Map中存储Key-value键值对
2.Map
2.1map说明
Map官方文档:Map (Java Platform SE 8 )
注意:
1.Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或HashMap;
2.Map中存放键值对的Key是唯一的,value是可重复的;
3.在TreeMap中插入键值对时,key不能为空,否则会抛出NullPointerException异常,value可以为空。但HashMap的key和value都可以为空;
Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复);
Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。
2.2TreeMap和HashMap
Map | TreeMap | HashMap |
---|---|---|
底层结构 | 红黑树 | 哈希桶 |
增删查改复杂度 | O(logN) | O(1) |
是否有序 | 关于key有序 | 无序 |
是否线程安全 | 不安全 | 不安全 |
增删查改区别 | 需要进行元素比较 | 通过哈希函数计算哈希地址 |
比较与覆写 | key必须可比较,否则会抛出ClassCastException异常 | 自定义类型需要覆写equals和hashCode方法 |
应用场景 | 需要在key有序场景下 | key是否有序不关心,需要更高的时间性能 |
2.3常用方法
方法 | 说明 |
---|---|
V get (Object key ) | 返回key对应的value |
V getOrDefault (Object key, V defaultValue) | 返回key对应的value, key不存在返回默认值 |
V put (K key, V value) | 设置key对应的value |
V remove (Object key) | 删除key对应的映射关系 |
Set<K> keySet () | 返回所有 key 的不重复集合 |
Collection<V> values () | 返回所有 value 的可重复集合 |
Set<Map.Entry<K, V>> entrySet () | 返回所有的 key-value 映射关系 |
boolean containsKey (Object key) | 判断是否包含 key |
boolean containsValues (Object value) | 判断是否包含 value |
3.Set
3.1set说明
Set官方文档:Set (Java Platform SE 8 )
注意:
Set是继承自Collection的一个接口类;
Set中只存储key,并且要求key一定要唯一;
TreeSet的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的;
Set最大的功能就是对集合中的元素进行去重;
实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序;
Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入;
TreeSet中不能插入null的key,HashSet可以。
3.2TreeSet和HashSet
类TreeMap和HashMap:
Set底层结构 | TreeSet | HashSet |
---|---|---|
底层结构 | 红黑树 | 哈希桶 |
增删查改时间复杂度 | O(logN) | O(1) |
是否有序 | 关于key有序 | 不一定有序 |
线程安全 | 不安全 | 不安全 |
增删查改区别 | 按照红黑树的特性进行插入和删除 | 先计算key哈希地址,再进行插入和删除 |
比较与覆写 | key必须可比较,否则会抛出ClassCastException异常 | 自定义类型需要覆写equals和hashCode方法 |
应用场景 | 需要在key有序场景下 | key是否有序不关心,需要更高的时间性能 |
3.3常用方法
方法 | 说明 |
---|---|
boolean add ( E e ) | 添加元素,但重复元素不会被添加成功 |
void clear () | 清空集合 |
boolean contains ( Object o ) | 判断 o 是否在集合中 |
Iterator<E> iterator () | 返回迭代器 |
boolean remove ( Object o ) | 删除集合中的 o |
int size () | 返回 set 中元素的个数 |
boolean isEmpty () | 检测 set 是否为空 |
Object [] toArray () | 将 set 中的元素转换为数组返回 |
boolean containsAll ( Collection<?> c ) | 判断集合 c 中的元素是否在 set 中全部存在 |
boolean addAll ( Collection<? extends E> c ) | 将集合c中的元素添加到 set 中,达到去重效果 |